MST
星途 面试题库

面试题:Swift的Core Animation中如何创建一个沿特定路径运动的动画

假设在Swift项目中有一个圆形视图,要求使用Core Animation创建一个使其沿着正弦曲线的路径运动的动画,阐述实现思路并给出关键代码片段,需处理好路径绘制、动画设置及性能优化等方面。
42.6万 热度难度
编程语言Swift

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 路径绘制:根据正弦曲线的数学公式,计算出一系列点的坐标,然后使用UIBezierPath来创建路径。正弦曲线公式为 y = A * sin(B * x + C) + D,其中 A 是振幅,B 影响周期,C 是相位,D 是垂直偏移。
  2. 动画设置:使用 CAKeyframeAnimation,将绘制好的路径赋值给动画的 path 属性,设置动画的时长、重复次数等参数。
  3. 性能优化
    • 尽量减少计算量,提前计算好路径上的点。
    • 使用 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
    }
}