实现思路
- 路径绘制:根据正弦曲线的数学公式,计算出一系列点的坐标,然后使用
UIBezierPath
来创建路径。正弦曲线公式为 y = A * sin(B * x + C) + D
,其中 A
是振幅,B
影响周期,C
是相位,D
是垂直偏移。
- 动画设置:使用
CAKeyframeAnimation
,将绘制好的路径赋值给动画的 path
属性,设置动画的时长、重复次数等参数。
- 性能优化:
- 尽量减少计算量,提前计算好路径上的点。
- 使用
CADisplayLink
来控制动画的更新频率,避免不必要的重绘。
- 确保视图的
layer
被设置为 shouldRasterize
,以提高渲染性能。
关键代码片段
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let circularView = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
circularView.backgroundColor = .red
circularView.layer.cornerRadius = 25
view.addSubview(circularView)
// 路径绘制
let path = UIBezierPath()
let amplitude: CGFloat = 100 // 振幅
let period: CGFloat = 2 * .pi // 周期
let phase: CGFloat = 0 // 相位
let verticalOffset: CGFloat = view.bounds.midY // 垂直偏移
let numPoints = 100
for i in 0..<numPoints {
let x = CGFloat(i) * view.bounds.width / CGFloat(numPoints)
let y = amplitude * sin((2 * .pi / period) * x + phase) + verticalOffset
if i == 0 {
path.move(to: CGPoint(x: x, y: y))
} else {
path.addLine(to: CGPoint(x: x, y: y))
}
}
// 动画设置
let animation = CAKeyframeAnimation(keyPath: "position")
animation.path = path.cgPath
animation.duration = 5
animation.repeatCount = .greatestFiniteMagnitude
animation.calculationMode = .paced
circularView.layer.add(animation, forKey: "sineWaveAnimation")
// 性能优化
circularView.layer.shouldRasterize = true
circularView.layer.rasterizationScale = UIScreen.main.scale
}
}