CALayer遮罩动画完成后未消失问题求助
解决遮罩动画结束后恢复原状的问题
嘿,我来帮你搞定这个问题~你遇到的情况其实是Core Animation的一个常见特性导致的:CAKeyframeAnimation默认只是临时修改图层的视觉表现,动画结束后会自动还原到图层的原始属性值,所以你的遮罩会变回初始的120x100大小,而不是保持放大后的状态。
解决方案:让动画结束后保持最终状态
你需要做两个关键设置,同时手动更新图层的实际属性,确保视觉和数据一致:
- 给动画添加
fillMode = .forwards和removedOnCompletion = false,让动画结束后停留在最后一帧 - 手动更新
mask的bounds属性,同步到动画的最终值(因为动画只修改「呈现层」,不会改「模型层」的属性)
修改后的代码
把你原来的动画代码替换成下面这段:
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) { let keyFrameAnimation = CAKeyframeAnimation(keyPath: "bounds") keyFrameAnimation.duration = 1 keyFrameAnimation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut), CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)] let initialBounds = NSValue(cgRect: self.mask!.bounds) let secondBounds = NSValue(cgRect: CGRect(x: 0, y: 0, width: 110, height: 90)) let finalBounds = NSValue(cgRect: CGRect(x: 0, y: 0, width: 6000, height: 5000)) keyFrameAnimation.values = [initialBounds, secondBounds, finalBounds] keyFrameAnimation.keyTimes = [0, 0.3, 1] // 关键设置:动画结束后保持最后一帧状态 keyFrameAnimation.fillMode = .forwards keyFrameAnimation.removedOnCompletion = false self.mask!.add(keyFrameAnimation, forKey: "bounds") // 同步更新mask的实际bounds,避免后续操作导致状态回退 self.mask?.bounds = finalBounds.cgRectValue }
原理说明
fillMode = .forwards:告诉动画在结束后保持最后一帧的视觉效果removedOnCompletion = false:防止动画完成后被系统自动移除,这样fillMode的设置才能生效- 手动更新
bounds:Core Animation的动画是作用在「呈现层」(layer.presentation())上的,不会修改「模型层」(layer本身)的属性。如果只靠fillMode,后续如果对图层有其他操作,可能会触发重绘,导致状态回退到原始值,所以手动同步模型层的属性是更稳妥的做法。
内容的提问来源于stack exchange,提问作者Steve Left
相关产品推荐
相关产品推荐

