自定义iOS转场:dismiss视图控制器时出现白屏问题求助
解决iOS Hero动画Dismiss时的白屏问题
嘿,我看了你的代码和问题描述,这个dismiss时的短暂白屏大概率是转场过程中视图层级管理不当导致的——当你收起详情页时,底层的列表页没有及时显示在容器视图里,就会露出空白背景。结合你的代码,给你几个具体的修改点:
1. Dismiss时先把列表页(toView)添加到容器底层
在dismiss的分支(!presenting)里,动画开始前先把原来的列表页(也就是transitionContext.view(forKey: .to))插入到容器视图的最底部,这样详情页缩小的过程中,下面始终有列表页作为背景,不会出现白屏:
if(!presenting){ // 关键:把列表页添加到容器最底层,避免空白 guard let toView = transitionContext.view(forKey: .to) else { transitionContext.completeTransition(false) return } containerView.insertSubview(toView, at: 0) edgeLayoutConstraints?.constants(to: 0) let animator = UIViewPropertyAnimator(duration: duration, dampingRatio: 0.8) animator.addAnimations { self.edgeLayoutConstraints?.match(to: self.originFrame, container: containerView) containerView.layoutIfNeeded() modalView.layoutIfNeeded() } // ... 其他代码 }
2. 动画完成后正确清理视图层级
在dismiss的动画完成回调里,记得把详情页(modalView)从容器中移除,避免多余视图留在层级里导致后续问题,同时修正completeTransition的参数(动画取消时应该传false):
animator.addCompletion { position in switch position { case .end: modalView.removeFromSuperview() // 清理视图 transitionContext.completeTransition(true) default: transitionContext.completeTransition(false) // 动画取消时传false } }
3. 检查Present分支的视图添加逻辑
虽然present时动画正常,但可以补充确保列表页在容器中作为背景(有些场景下系统不会自动添加):
else { modalView.translatesAutoresizingMaskIntoConstraints = false // 确保列表页在容器中作为背景 if let fromView = transitionContext.view(forKey: .from) { containerView.addSubview(fromView) } containerView.addSubview(toView) // ... 其他代码 }
额外排查点
- 确认你的
originFrame保存的是正确的坐标(相对于容器视图的坐标),如果坐标系转换错误,可能导致动画结束时视图位置不对,间接引发白屏; - 检查详情页的背景色是否设置为透明?如果详情页背景是不透明的,缩小过程中会遮挡底层,但你这里是白屏,所以应该不是这个问题,但可以确认下。
按照上面的修改调整后,dismiss时的白屏应该就能解决了。
内容的提问来源于stack exchange,提问作者Ajay Singh Beniwal
相关产品推荐
相关产品推荐

