pushViewController时UINavigationBar出现短暂异常渐变问题求助
这种导航栏过渡时的视觉小问题我之前也碰到过,大概率是dismiss和push的动画时序冲突导致的——dismiss的动画还没完全收尾,导航栏的布局状态还没回到稳定状态,这时候立刻触发push,两种过渡动画的布局更新撞在一起,就出现了短暂的渐变/遮罩效果。下面给你几个可行的解决方案:
方案1:延迟push操作,等dismiss动画完全结束
最简单直接的办法就是在dismiss的completion里延迟一小段时间再执行push,给系统足够的时间完成dismiss的动画和布局恢复。一般0.2秒左右就足够适配大多数设备的动画时长:
// 假设presentVC是你当前弹出的视图控制器,newVC是要推入的新控制器 presentVC.dismiss(animated: true) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { self.navigationController?.pushViewController(newVC, animated: true) } }
方案2:恢复导航栏的原始状态(如果present的VC修改过导航栏)
如果你的弹出视图(present的VC)在显示期间修改过导航栏的属性(比如隐藏、透明度、背景色等),一定要在它消失前把导航栏恢复到初始状态,避免残留状态影响后续的push过渡:
在present的VC中添加:
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 恢复导航栏的原始状态,根据你实际修改的属性调整 navigationController?.navigationBar.isHidden = false navigationController?.navigationBar.alpha = 1.0 navigationController?.navigationBar.barTintColor = originalBarTintColor // 替换成你原来的导航栏颜色 }
方案3:清除导航栏的残留动画后再push
有时候dismiss动画会给导航栏留下未完成的动画,导致push时出现冲突。可以在completion里先清除导航栏的所有动画,再执行push:
presentVC.dismiss(animated: true) { [weak self] in guard let self = self else { return } self.navigationController?.navigationBar.layer.removeAllAnimations() self.navigationController?.pushViewController(newVC, animated: true) }
方案4:强制刷新布局后再push
在dismiss完成后,先强制导航控制器的视图完成布局更新,确保导航栏状态稳定后再push:
presentVC.dismiss(animated: true) { self.navigationController?.view.layoutIfNeeded() self.navigationController?.pushViewController(newVC, animated: true) }
你可以先试试方案1,因为它最容易实现;如果问题依然存在,再检查是不是present的VC修改了导航栏属性,用方案2来修复。
内容的提问来源于stack exchange,提问作者Teddy K
相关产品推荐
相关产品推荐

