You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 10:18:08