isRemovedOnCompletion无效:动画结束后moonImageView尺寸恢复如何解决?
问题修复:动画结束后保持ImageView的放大状态
问题原因
你确实误解了isRemovedOnCompletion的作用——这个属性只是让动画对象结束后不被从图层移除,但Core Animation本质是修改图层的「呈现层」(Presentation Layer),而非「模型层」(Model Layer)。动画运行时你看到的是呈现层的临时状态,模型层的transform.scale始终是初始值1,所以动画结束后,图层会立刻回弹到模型层的原始状态。
两种可行修复方案
方案一:直接修改模型层属性(推荐)
在添加动画前,先把ImageView图层的实际transform设置为目标状态,动画结束后模型层已经是最终状态,就不会回弹:
@objc private func moonClick() { // 先设置模型层的最终放大状态 moonImageView.layer.transform = CATransform3DMakeScale(1.25, 1.25, 1.0) let moonAnimation = CABasicAnimation(keyPath: "transform.scale") moonAnimation.fromValue = 1 moonAnimation.toValue = 1.25 moonAnimation.duration = 0.25 moonImageView.layer.add(moonAnimation, forKey: nil) }
方案二:结合fillMode与isRemovedOnCompletion
如果不想直接修改模型层,需要同时设置fillMode = .forwards和isRemovedOnCompletion = false,强制动画结束后停留在最终帧:
@objc private func moonClick() { let moonAnimation = CABasicAnimation(keyPath: "transform.scale") moonAnimation.fromValue = 1 moonAnimation.toValue = 1.25 moonAnimation.duration = 0.25 moonAnimation.isRemovedOnCompletion = false // 添加fillMode,让动画保持结束帧状态 moonAnimation.fillMode = .forwards moonImageView.layer.add(moonAnimation, forKey: nil) }
注意:方案二的局限性是模型层属性并未真正改变,只是呈现层被动画最终帧覆盖。之后读取
transform.scale时,得到的还是初始值1而非1.25,所以更推荐方案一。
约束相关说明
你给ImageView设置了固定宽高约束(150x150),但Core Animation修改的是图层的transform,属于布局后的视觉变换,不会触发约束冲突,无需调整约束。
内容的提问来源于stack exchange,提问作者Steven-Carrot
相关产品推荐
相关产品推荐

