![](/img/trans.png)
[英]CABasicAnimation used for a chronometer animation doesn't work with iOS 8+
[英]CABasicAnimation in uitableviewcell doesn't seem to work
我正在尝试使用 CABasicAnimation 在 tableview 单元格中更改背景颜色中的标签,但它似乎不起作用 - 单元格背景颜色保持纯色,没有动画。 此代码在 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;
}
请注意,iOS 有一个 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")
}
}
还有更多!
不幸的是,只有一种方法可以解决这个问题。 老实说,这是唯一的办法。 (.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 中查看两行core magic 。 我懒得解释,但不管有没有那个,都可以尝试一下; 除非同步,否则它看起来很粗糙!
我想出了问题,虽然我不确定为什么会这样。 如果其他人可以添加到这个答案,请随意。
看起来好像设置单元格标签的背景颜色隐藏了图层的动画。 如果我注释掉标签的 backgroundColor 设置或使用 cell.label.layer.backgroundColor,它就可以工作。
让我感到困惑的是,在单元格的上下文之外,例如,如果您只是在常规视图中设置标签,则可以设置 backgroundColor 并且仍然可以看到动画。
这个问题是在 5 年前提出的,但仍然有人可能会使用这个答案,所以只需在 UITableViewCell 上执行以下操作。 这应该有效。
override func layoutSubviews() {
super.layoutSubviews()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
self.doAnimation()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.