Swift iOS实现UIView边框蛇形动画(支持圆角)的连续动画问题
Swift iOS实现UIView边框蛇形动画(支持圆角)的连续动画问题
嘿,我来帮你搞定这个边框蛇形动画不连续的问题,还能完美支持圆角哦~
你当前的动画之所以会出现“完成后从别的位置重新开始”的跳变问题,核心原因是动画结束后strokeStart停在0.8、strokeEnd停在1.0,下一次循环又突然跳回0和0.2,状态衔接不上。咱们调整一下动画逻辑,就能实现无缝循环的蛇形效果啦:
第一步:初始化带圆角的边框ShapeLayer
先把基础的ShapeLayer配置好,确保圆角生效,同时初始状态和动画起始状态对齐,避免第一次启动时的跳变:
let borderShapeLayer = CAShapeLayer() // 用roundedRect创建带圆角的路径,支持指定任意圆角组合 borderShapeLayer.path = UIBezierPath(roundedRect: contentView.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 15, height: 15)).cgPath borderShapeLayer.fillColor = UIColor.clear.cgColor // 填充色透明,只显示边框 borderShapeLayer.strokeColor = UIColor.red.cgColor // 边框颜色 borderShapeLayer.lineWidth = 5 // 边框宽度 // 设置初始状态,和动画起始状态一致,避免首次加载的突兀感 borderShapeLayer.strokeStart = 0 borderShapeLayer.strokeEnd = 0.2
第二步:创建无缝循环的动画组
关键是让strokeStart和strokeEnd的动画范围超出0-1区间,保证循环前后的状态差值一致,实现无缝衔接:
// strokeStart动画:从0移动到1,全程覆盖整个边框路径 let startAnimation = CABasicAnimation(keyPath: "strokeStart") startAnimation.fromValue = 0 startAnimation.toValue = 1.0 startAnimation.duration = 20 startAnimation.timingFunction = CAMediaTimingFunction(name: .linear) // 匀速移动,更自然 // strokeEnd动画:从0.2移动到1.2,始终保持和strokeStart的差值为0.2(也就是蛇形的长度) let endAnimation = CABasicAnimation(keyPath: "strokeEnd") endAnimation.fromValue = 0.2 endAnimation.toValue = 1.2 endAnimation.duration = 20 endAnimation.timingFunction = CAMediaTimingFunction(name: .linear) // 组合动画组 let animationGroup = CAAnimationGroup() animationGroup.animations = [startAnimation, endAnimation] animationGroup.duration = 20 animationGroup.repeatCount = .infinity // 无限循环 // 重要:动画结束后保留最终状态,不重置,保证循环衔接 animationGroup.isRemovedOnCompletion = false animationGroup.fillMode = .forwards // 添加动画到图层 borderShapeLayer.add(animationGroup, forKey: "ContinuousSnakeBorderAnimation") contentView.layer.addSublayer(borderShapeLayer)
额外优化:适配view尺寸变化
如果你的contentView会因为布局调整、屏幕旋转等改变尺寸,记得在layoutSubviews里更新ShapeLayer的路径,保证边框始终贴合view:
override func layoutSubviews() { super.layoutSubviews() borderShapeLayer.path = UIBezierPath(roundedRect: contentView.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 15, height: 15)).cgPath }
这样调整后,动画就会一直连续地沿着边框蛇形移动,不会出现跳变啦~
备注:内容来源于stack exchange,提问作者Saranjith
相关产品推荐
相关产品推荐

