修复类似TikTok交互式Push过渡中TabBar动画异常问题
修复交互式Push过渡中TabBar动画不一致的问题
这个问题的核心在于:当你设置viewController.hidesBottomBarWhenPushed = true时,系统默认的Push过渡会自动同步TabBar的隐藏动画,但你的自定义PushAnimatedTransitioning没有处理TabBar的状态变化,导致它和页面过渡动画脱节。
下面是具体的修复方案,主要是在自定义过渡动画中加入TabBar的同步动画,并处理过渡取消的回滚逻辑:
修改后的PushAnimatedTransitioning代码
class PushAnimatedTransitioning : NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.3 } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let fromVC = transitionContext.viewController(forKey: .from), let toVC = transitionContext.viewController(forKey: .to), let tabBar = fromVC.tabBarController?.tabBar else { transitionContext.completeTransition(false) return } let containerView = transitionContext.containerView let duration = transitionDuration(using: transitionContext) let finalFrame = transitionContext.finalFrame(for: toVC) // 初始化目标控制器视图位置 toVC.view.frame = finalFrame toVC.view.center.x += containerView.bounds.width containerView.addSubview(toVC.view) // 记录TabBar初始alpha(兼容原本就隐藏的情况) let originalTabBarAlpha = tabBar.alpha UIView.animate(withDuration: duration, animations: { // 页面过渡动画 fromVC.view.center.x -= containerView.bounds.width / 2 toVC.view.center.x -= containerView.bounds.width // 同步TabBar隐藏动画,和页面过渡时长一致 tabBar.alpha = 0 }) { transitionCompleted in let transitionCancelled = transitionContext.transitionWasCancelled // 过渡取消时,恢复TabBar原始状态并移除目标视图 if transitionCancelled { tabBar.alpha = originalTabBarAlpha toVC.view.removeFromSuperview() } else { // 过渡完成后确保TabBar保持隐藏 tabBar.alpha = 0 } transitionContext.completeTransition(!transitionCancelled) } } }
额外优化建议
- Pop过渡时恢复TabBar:在对应的Pop过渡动画类中,记得添加TabBar从alpha=0恢复到1的动画,保持和系统默认Pop行为一致。
- 避免手势冲突:当前
InteractiveNavigationController直接给整个view添加了Pan手势,建议限制手势触发区域(比如仅在屏幕右侧边缘触发Push手势),或者设置gestureRecognizer.cancelsTouchesInView = false,避免和系统自带的Pop手势冲突。
关键逻辑说明
- 动画开始时获取源控制器的TabBar,记录它的初始透明度,确保过渡取消时能准确恢复状态。
- 在页面滑动的动画块中,同步修改TabBar的透明度,让它的隐藏动画和页面过渡完全同步。
- 过渡结束时根据是否取消,分别处理TabBar的最终状态:取消则回滚到原始状态,完成则保持隐藏。
这样修改后,TabBar的动画就会和自定义Push过渡完美同步,和系统默认Push的表现完全一致了。
内容的提问来源于stack exchange,提问作者son
相关产品推荐
相关产品推荐

