Swift添加UIView后立即执行动画出现反向效果如何解决
问题根因
- 代码中设置了
translatesAutoresizingMaskIntoConstraints = false,采用Auto Layout规则布局,此时直接修改frame属性做动画属于错误用法,Auto Layout会在系统布局阶段自动覆盖手动写入的frame值。 - 约束激活后不会立即完成布局计算,调用动画代码时系统还未将视图放置到约束指定的中心点位置,会把动画块中设置的上移300点的frame作为初始渲染位置,待布局流程执行完成后自动将视图归位到中心点约束位置,最终呈现完全反向的动画效果。
修复方案
无需提前创建视图,只需在激活约束后先强制系统完成初始布局,再通过更新约束常量的方式实现动画即可,修正后代码如下:
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } @IBAction func buttonTapped(_ sender: Any) { let square = UIView() square.backgroundColor = .red square.translatesAutoresizingMaskIntoConstraints = false view.addSubview(square) // 单独持有需要做动画的Y轴中心约束引用 let centerYConstraint = square.centerYAnchor.constraint(equalTo: view.centerYAnchor) [square.widthAnchor.constraint(equalToConstant: 100), square.heightAnchor.constraint(equalToConstant: 100), square.centerXAnchor.constraint(equalTo: view.centerXAnchor), centerYConstraint].forEach { $0.isActive = true } // 强制立即完成初始布局,确保视图首先渲染在中心点的预期初始位置 view.layoutIfNeeded() // 更新约束常量,在动画块内触发布局更新实现正向动画 UIView.animate(withDuration: 2.0) { centerYConstraint.constant = -300 self.view.layoutIfNeeded() } } }
开发提示:使用Auto Layout时,所有位置、尺寸相关的动画都应通过调整约束
constant值、配合layoutIfNeeded()实现,直接修改frame会导致布局被覆盖、动画异常等问题。
效果参考
注释动画代码时,视图初始渲染位置符合预期:
修复前的异常反向动画效果:
修复后动画逻辑完全符合预期:视图首先在中心点渲染完成,随后沿Y轴负方向移动300点移出屏幕。
内容的提问来源于stack exchange,提问作者Mr.P
相关产品推荐
相关产品推荐

