简体   繁体   English

uitableviewcell 中的 CABasicAnimation 似乎不起作用

[英]CABasicAnimation in uitableviewcell doesn't seem to work

I'm trying to make a label within a tableview cell change background color with a CABasicAnimation and it doesn't seem to be working - the cell background color remains solid with no animation.我正在尝试使用 CABasicAnimation 在 tableview 单元格中更改背景颜色中的标签,但它似乎不起作用 - 单元格背景颜色保持纯色,没有动画。 This code is in the cellForRowAtIndexPath method此代码在 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;
}

Note that iOS has a known problem with UILabel:请注意,iOS 有一个 UILabel 的已知问题

you have to set the bg color of UILabel to clear, before you can fool with the color or animate it.您必须将 UILabel 的 bg 颜色设置为清除,然后才能愚弄颜色或为其设置动画。

It's just one of those things about iOS.这只是关于 iOS 的事情之一。

The following works great:以下效果很好:

Small text badge, where the background color throbs, throbs, throbs:小文字徽章,背景色抽动,抽动,抽动:

In storyboard, simply set the bg color to say black just so you can see what you're doing.在故事板中,只需将背景颜色设置为黑色,这样您就可以看到自己在做什么。 (The IBDesignable system is not good enough, as of writing, to render the bounce animation in storyboard.) (在编写时,IBDesignable 系统还不够好,无法在故事板中渲染反弹动画。)

Naturally, you can add an @IBInspectable just to set the color bounce - but why when red/orange is so good!?当然,您可以添加一个 @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")
    }
}

There's more!还有更多!

When table view cells disappear in iOS, any layer animations are killed - boo!当表视图单元格在 iOS 中消失时,任何图层动画都会被杀死 - 嘘!

Unfortunately there is only one way to deal with this .不幸的是,只有一种方法可以解决这个问题 Honest, it's the only way.老实说,这是唯一的办法。 (.isRemovedOnCompletion does not help here.) (.isRemovedOnCompletion 在这里没有帮助。)

In your table view , add在您的表视图中,添加

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

Then in your cell class,然后在你的细胞课上,

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

...

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

} }

That is, unfortunately, the only way for now for a cell to know it is appearing.不幸的是,这是细胞现在知道它出现的唯一方法。

Simply call the "doAnimation"s in that function.只需在该函数中调用“doAnimation”即可。

Finally, syncing the pulses!最后,同步脉冲!

Look in doAnimation at the two lines core magic .在 doAnimation 中查看两行core magic I can't be bothered explaining, but try it with and without that;我懒得解释,但不管有没有那个,都可以尝试一下; it looks shoddy unless it is synced!除非同步,否则它看起来很粗糙!

I figured out the problem, though I'm not sure why it is the case.我想出了问题,虽然我不确定为什么会这样。 If somebody else can add to this answer, please feel free.如果其他人可以添加到这个答案,请随意。

It looks as though setting the background color of the cell label was hiding the animation of the layer.看起来好像设置单元格标签的背景颜色隐藏了图层的动画。 If I comment out the backgroundColor setting for the label OR use cell.label.layer.backgroundColor, it works.如果我注释掉标签的 backgroundColor 设置或使用 cell.label.layer.backgroundColor,它就可以工作。

What confuses me is that outside of the context of the cell, for instance if you just set a label within a regular view, you can set the backgroundColor and still see the animation.让我感到困惑的是,在单元格的上下文之外,例如,如果您只是在常规视图中设置标签,则可以设置 backgroundColor 并且仍然可以看到动画。

The question was asked more than 5 years ago but still someone might use this answer so just do the following on UITableViewCell.这个问题是在 5 年前提出的,但仍然有人可能会使用这个答案,所以只需在 UITableViewCell 上执行以下操作。 This should work.这应该有效。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM