【问题标题】:CABasicAnimation in uitableviewcell doesn't seem to workuitableviewcell 中的 CABasicAnimation 似乎不起作用
【发布时间】:2014-11-15 00:23:04
【问题描述】:

我正在尝试使用 CABasicAnimation 更改表格视图单元格中的标签,但它似乎不起作用 - 单元格背景颜色保持不变,没有动画。 这段代码在 cellForRowAtIndexPath 方法中

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MainCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
NSString *name = @"Hello";
UIColor *color = [UIColor colorWithRed:0.0f/255.0f green:100.0f/255.0f blue:200.0f/255.0f alpha:1.0f];

// I'm setting the label as a strong property of the cell 
cell.label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, cell.contentView.frame.size.height)]; 

cell.label.text = name;

cell.label.textColor = [UIColor whiteColor];
cell.label.backgroundColor = color;
[cell.contentView addSubview:cell.label];


UIColor *endColor = [UIColor redColor];
CABasicAnimation *animation;
animation=[CABasicAnimation animationWithKeyPath:@"backgroundColor"];
animation.duration=0.7;
animation.repeatCount=HUGE_VALF;
animation.autoreverses=YES;
animation.fromValue=(id)color.CGColor;
animation.toValue=(id)endColor.CGColor;
[cell.label.layer addAnimation:animation forKey:@"pulses"];

return cell;
}

【问题讨论】:

  • 该代码对我来说很好用。你确定“标签”不是零。
  • @rdelmar - 你是在表格视图中这样做的吗?你可以发送示例代码吗?这在 tableviewcell 的上下文之外工作,但我还没有让它在 tableviewcell 中工作。
  • 我复制了你的代码,并把它放在 cellFroRowAtIndexPath 中,就像你说的那样。我所做的唯一添加是添加一行来定义“颜色”(用于 fromValue),并且在最后一行中,“cell.label”而不是“label”(我的单元格有一个名为 label 的 IBOutlet)。你检查过“标签”不是零吗?
  • @rdelmar - 我刚刚在方法中添加了我的整个代码块。你能和你的比较一下,看看有什么不同吗?这不是动画...我在 iOS8 上运行它...

标签: ios uitableview quartz-core cabasicanimation


【解决方案1】:

请注意,iOS 有一个与 UILabel 相关的已知问题

您必须将 UILabel 的背景颜色设置为清除,然后才能欺骗颜色或对其进行动画处理。

这只是关于 iOS 的其中之一。

以下效果很好:

小文字徽章,其中背景色跳动,跳动,跳动:

在情节提要中,只需将背景颜色设置为黑色,这样您就可以看到自己在做什么。 (截至撰写本文时,IBDesignable 系统还不足以在情节提要中呈现弹跳动画。)

当然,您可以添加一个@IBInspectable 来设置颜色反弹 - 但是为什么当红色/橙色这么好时!? :)

@IBDesignable class ColorTextBadge: UILabel {
    
    override var text: String? {
        didSet {
            print("Text changed from \(oldValue) to \(text)")
            // very often, you'll want to change the color or whatever
            // when this happens
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        initialSetup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        initialSetup()
    }

    func initialSetup() {
        // this will only happen ONCE

        // annoyingly, you have to, in a word, do this to make color bg animations work, on a UILabel:
        backgroundColor = UIColor.clear
        
        // also, shape the corners...easy
        let r = self.bounds.size.height / 2
        let path = UIBezierPath(roundedRect: self.bounds, cornerRadius:r)
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        self.layer.mask = mask
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        doAnimation()
        // you will have to restart the animation EACH TIME
        // the label is shaped by layout.
    }
    
    func doAnimation() {
        
        layer.removeAnimation(forKey: "bounce")
        
        let bounce = CABasicAnimation(keyPath: "backgroundColor")
        bounce.fromValue = sfRed.cgColor
        bounce.toValue = UIColor.orange.cgColor
        
        // core magic:
        let ct = CACurrentMediaTime().truncatingRemainder(dividingBy: 1)
        bounce.timeOffset = ct
        
        bounce.duration = 0.5
        bounce.autoreverses = true
        bounce.repeatCount = Float.greatestFiniteMagnitude
        
        bounce.isRemovedOnCompletion = false
        
        layer.add(bounce, forKey: "bounce")
    }
}

还有更多!

当表格视图单元格在 iOS 中消失时,任何图层动画都会被杀死 - 嘘!

不幸的是只有一种方法可以解决这个问题。老实说,这是唯一的方法。 (.isRemovedOnCompletion 在这里没有帮助。)

在您的表格视图中,添加

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if let c = cell as? ActivityCell {
        c.cellWillDisplaySignalling()
    }
}

然后在你的单元格中,

类 YourCell: UITableViewCell { @IBOutlet var blah:UILabel! @IBOutlet var blah:UILabel! @IBOutlet var aBadge:ColorTextBadge! @IBOutlet var anotherBadge: ColorTextBadge!

...

override func cellWillDisplaySignalling() {
    aBadge.doAnimation()
    anotherBadge.doAnimation()
}

}

不幸的是,这是目前让细胞知道它出现的唯一方法。

只需在该函数中调用“doAnimation”即可。

最后,同步脉冲!

查看 doAnimation 中的两行 core magic。我懒得解释,但不管有没有,都可以试试;除非它被同步,否则它看起来很次品!

【讨论】:

    【解决方案2】:

    我发现了问题所在,但我不确定为什么会这样。如果其他人可以添加此答案,请随时。

    看起来好像设置单元格标签的背景颜色隐藏了图层的动画。如果我注释掉标签的 backgroundColor 设置或使用 cell.label.layer.backgroundColor,它可以工作。

    让我感到困惑的是,在单元格上下文之外,例如,如果您只是在常规视图中设置标签,则可以设置 backgroundColor 并且仍然可以看到动画。

    【讨论】:

    • 设置标签的背景色时,在独立标签中看不到任何动画;似乎 UILabel 的背景颜色绘制在标签层的前面。该层是一个名为 _UILabelLayer 的私有类型。这与图层类为 CALayer 的普通 UIView 不同,并且在该图层中绘制视图的背景颜色(如果您记录 self.backgroundColor 和 self.layer.backgroundColor,您将获得相同的 UIView 值)。当您在独立标签中测试动画时,背景颜色的 alpha 是否设置为 1?
    【解决方案3】:

    这个问题是 5 年前提出的,但仍然有人可能会使用这个答案,所以只需在 UITableViewCell 上执行以下操作。这应该可以。

    override func layoutSubviews() {
        super.layoutSubviews()
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
            self.doAnimation()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-11-29
      • 2016-02-01
      • 2020-09-23
      • 2010-12-05
      • 2011-06-14
      • 2015-01-10
      • 2016-02-24
      • 2011-01-18
      • 2018-06-20
      相关资源
      最近更新 更多