uitableviewcell中的CABasicAnimation似乎不起作用

时间:2014-11-15 00:23:05

标签: ios uitableview quartz-core cabasicanimation

我试图在tableview单元格中使用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;
}

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

问题似乎与UILabel有关。

似乎很烦人,

您必须先将UILabel的bg颜色设置为清除,然后才能使用颜色或为其设置动画。

以下效果很好:

小文字徽章,其中背景颜色为throbs,throbs,throbs:

在故事板中,只需将bg颜色设置为黑色,这样就可以看到你正在做什么。 (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()
    }
}

然后在你的手机课上,

class 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。我不能被解释,但是有没有那个尝试;除非它被同步,否则看起来很糟糕!

答案 2 :(得分:0)

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

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