求助:UIViewPropertyAnimator弹出其他控制器后停止工作
解决UIViewPropertyAnimator在弹出控制器后停止工作的问题
这个问题其实挺常见的——当你present另一个控制器(尤其是全屏类型)时,当前控制器的视图会被移出窗口,UIViewPropertyAnimator因为依赖活跃的窗口环境和RunLoop,就会自动暂停甚至终止动画。再加上默认情况下动画完成后会进入不可复用状态,导致回到原控制器后没法继续执行。下面给你几个可行的解决方案:
1. 保存动画进度,在控制器回到前台时恢复
核心思路是在当前控制器即将消失时,记录动画的当前进度并暂停;当控制器重新显示时,恢复进度并继续动画。
步骤1:添加属性保存进度
在你的视图控制器里新增一个属性,用来记录动画的进度:
@property (nonatomic, assign) CGFloat headerAnimationProgress;
步骤2:修改动画初始化,开启暂停保留
初始化headerAnimator时,设置pausesOnCompletion = YES,这样动画完成后不会自动进入不可用状态,方便后续复用:
- (UIViewPropertyAnimator *)headerAnimator { if (!_headerAnimator) { _headerAnimator = [[UIViewPropertyAnimator alloc] initWithDuration:2.f curve:UIViewAnimationCurveLinear animations:^{ self.profileImageBorderWidthConstraint.constant = 58.f; self.profileImageBorderHeightConstraint.constant = 58.f; self.profileImageBorder.layer.cornerRadius = 29.f; self.profileImageView.layer.cornerRadius = 25.f; // 补全你的其他约束修改,比如nameLabelTopConstraint self.nameLabelTopConstraint.constant = 16.f; // 示例值,替换成你的实际需求 }]; // 关键设置:动画完成后不自动释放,保持可控制状态 _headerAnimator.pausesOnCompletion = YES; } return _headerAnimator; }
步骤3:在生命周期方法中处理暂停与恢复
重写视图控制器的viewWillDisappear:和viewWillAppear:方法,处理动画的暂停和恢复:
- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; // 如果动画正在运行,记录进度并暂停 if (self.headerAnimator.isRunning) { self.headerAnimationProgress = self.headerAnimator.fractionComplete; [self.headerAnimator pauseAnimation]; } } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // 恢复未完成的动画 if (self.headerAnimationProgress > 0 && self.headerAnimationProgress < 1) { // 恢复到之前的进度 self.headerAnimator.fractionComplete = self.headerAnimationProgress; // 继续动画 [self.headerAnimator startAnimation]; } }
2. 额外注意事项
- 如果你的动画是需要反复触发的(比如下拉放大、上滑缩小),可以考虑把动画设置为可逆的(
isReversed属性),这样恢复时可以更灵活地控制动画方向。 - 确保动画中修改的约束都是当前视图控制器的属性,避免引用已经被释放的对象。
- 如果present的是非全屏控制器,当前视图仍然在窗口中,动画可能不会停止,但为了兼容性,还是建议加上进度保存的逻辑。
这样处理后,即使弹出其他控制器,回来后动画也能从暂停的位置继续运行啦~
内容的提问来源于stack exchange,提问作者gklka
相关产品推荐
相关产品推荐

