如何在SwiftUI中实现同控制点数量的路径替换动画
原生SwiftUI实现同控制点数量路径的平滑过渡动画
我已经能实现strokeStart/strokeEnd这类属性的动画,现在想在SwiftUI里复刻CoreAnimation的路径替换效果——让两个控制点数量完全一致的路径平滑过渡,效果如下:

之前在UIKit中通过CABasicAnimation给CAShapeLayer替换同控制点数量的新路径实现了该效果,但现在想找纯SwiftUI的解决方案,不想用UIView封装的方式。
实现方案:自定义可动画Shape
SwiftUI的Shape遵循Animatable协议,我们可以通过自定义Shape,将路径的控制点作为可动画属性,实现路径的平滑过渡。
步骤:
- 自定义Shape,存储路径的控制点数组(必须保证前后路径的点数、点类型一致)
- 实现
animatableData,将控制点的x、y坐标拆分为可动画的数组 - 在
path(in:)中根据当前控制点构建路径
示例代码:
struct AnimatedBezierShape: Shape { // 存储贝塞尔曲线的控制点(示例为三次贝塞尔,每组包含起点+2个控制点+终点) var controlPoints: [CGPoint] // 实现可动画数据,将x、y坐标分别转为数组 var animatableData: AnimatablePair<[CGFloat], [CGFloat]> { get { let xs = controlPoints.map { $0.x } let ys = controlPoints.map { $0.y } return AnimatablePair(xs, ys) } set { let count = min(newValue.first.count, newValue.second.count) controlPoints = (0..<count).map { CGPoint(x: newValue.first[$0], y: newValue.second[$0]) } } } func path(in rect: CGRect) -> Path { var path = Path() guard controlPoints.count >= 4 else { return path } // 按三次贝塞尔曲线构建路径(示例为单条曲线,可扩展为多条) path.move(to: controlPoints[0]) path.addCurve(to: controlPoints[3], control1: controlPoints[1], control2: controlPoints[2]) return path } } // 使用示例 struct PathTransitionView: View { @State private var showTargetPath = false // 原始路径控制点(三次贝塞尔,4个点) let originalPoints: [CGPoint] = [ CGPoint(x: 50, y: 150), CGPoint(x: 100, y: 50), CGPoint(x: 200, y: 250), CGPoint(x: 250, y: 150) ] // 目标路径控制点(同样4个点,和原始路径类型一致) let targetPoints: [CGPoint] = [ CGPoint(x: 50, y: 150), CGPoint(x: 100, y: 250), CGPoint(x: 200, y: 50), CGPoint(x: 250, y: 150) ] var body: some View { AnimatedBezierShape(controlPoints: showTargetPath ? targetPoints : originalPoints) .stroke(.orange, lineWidth: 4) .frame(width: 300, height: 300) .onTapGesture { withAnimation(.easeInOut(duration: 1.5)) { showTargetPath.toggle() } } } }
注意事项:
- 必须保证前后路径的控制点数量、类型完全匹配:比如都是折线的点,或都是同数量的贝塞尔曲线控制点(三次贝塞尔每组4个点,两组路径的点数要一致),否则动画会出现跳变
- 如果是复杂路径(多段曲线/折线组合),需要确保两组路径的段数、每段的控制点数量一一对应
animatableData通过拆分x、y坐标数组,让SwiftUI能逐点插值动画,实现平滑过渡
内容的提问来源于stack exchange,提问作者Duncan C
相关产品推荐
相关产品推荐

