如何在UIView中展示启动动画?OnboardingController动画失效求助
解决OnboardingController中Page视图内UIImageView动画不生效的问题
问题根源
你将动画逻辑放在了Page类的init(frame:)方法中,此时视图尚未完成布局(Auto Layout约束还未计算出最终的frame),视图也还未被添加到视图层级并渲染到屏幕上,导致动画无法被系统正确触发。
解决方案一:在layoutSubviews中执行动画
layoutSubviews会在视图完成布局后被调用,是执行布局相关动画的合适时机。同时添加标记避免动画重复触发:
class Page: UIView { private let imageView: UIImageView = { let image = UIImageView() image.image = UIImage(named: "1") image.translatesAutoresizingMaskIntoConstraints = false return image }() // 标记动画是否已执行,防止重复触发 private var animationPlayed = false override init(frame: CGRect) { super.init(frame: frame) addSubview(imageView) // 批量激活约束,代码更简洁 NSLayoutConstraint.activate([ imageView.topAnchor.constraint(equalTo: topAnchor), imageView.bottomAnchor.constraint(equalTo: bottomAnchor), imageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: -120), imageView.trailingAnchor.constraint(equalTo: trailingAnchor) ]) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() guard !animationPlayed else { return } animationPlayed = true // 使用当前Swift语法的transform构造方法,替代已废弃的CGAffineTransformTranslate UIView.animate(withDuration: 7.0) { self.imageView.transform = CGAffineTransform(translationX: 120, y: 0) } } }
解决方案二:在控制器的viewDidAppear中触发动画
这种方式更可控,能明确控制动画触发时机:
- 给
Page类添加一个触发动画的方法:
class Page: UIView { private let imageView: UIImageView = { let image = UIImageView() image.image = UIImage(named: "1") image.translatesAutoresizingMaskIntoConstraints = false return image }() override init(frame: CGRect) { super.init(frame: frame) addSubview(imageView) NSLayoutConstraint.activate([ imageView.topAnchor.constraint(equalTo: topAnchor), imageView.bottomAnchor.constraint(equalTo: bottomAnchor), imageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: -120), imageView.trailingAnchor.constraint(equalTo: trailingAnchor) ]) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } // 暴露动画触发方法 func startAnimation() { UIView.animate(withDuration: 7.0) { self.imageView.transform = CGAffineTransform(translationX: 120, y: 0) } } }
- 在
OnboardingController的viewDidAppear方法中调用:
class OnboardingController: UIViewController { // ... 原有代码 ... override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) views.startAnimation() } }
额外优化点
- 用
NSLayoutConstraint.activate批量激活约束,替代单独设置isActive,代码更简洁易维护 - 替换已废弃的
CGAffineTransformTranslate为CGAffineTransform(translationX:y:),符合当前Swift语法规范
内容的提问来源于stack exchange,提问作者Alex Smith
相关产品推荐
相关产品推荐

