交互式转换:导航栏外观问题

可以说,我有3个视图控制器: ABC ,全部embedded到导航控制器中。 AB有一个导航栏, C没有。

我有一个自定义的BC之间的交互转换。 因为我需要我的导航栏消失在C ,我实现了UINavigationControllerDelegate这个function:

 func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { if viewController is C { navigationController.setNavigationBarHidden(true, animated: animated) } else { navigationController.setNavigationBarHidden(false, animated: animated) } } 

当我只进行push-pop转换时,一切都可以在一个普通的场景中完美运行。

但是,当我通过调用UIPercentDrivenInteractiveTransition上的cancel()取消转换B – > C ,导航栏不会显示在B 。 在这里,我必须调用setNavigationBarHidden(false, ...) ,但是我没有设法find正确的位置来做到这一点。

如果我在BviewWillAppear调用它,会出现一个导航栏,但看起来真的很奇怪 – 它包含了C会拥有的导航栏的元素。 如果我弹回到A ,它会闪烁片刻并显示预期的内容,但在过渡之后, A导航栏将被B导航栏取代!

所以,似乎导航栏堆栈在BC转换取消之后以某种方式被破坏,它似乎相对于视图控制器这样移动:

  has ----------------------------------------------- | ViewController | Navigation bar of | ----------------------------------------------- | A | B | ----------------------------------------------- | B | C | ----------------------------------------------- 

所以,我的问题是在这种情况下调用navigationController.setNavigationBarHidden(false, animated: true)的正确位置是什么?

那么,我已经设法find一个丑陋的黑客自己修复它。 也许在这个世界上有人会觉得有帮助。

  • 在我的自定义UIPercentDrivenInteractiveTransition我重写cancelfunction,如下所示:

     class CustomTransitionManager: UIPercentDrivenInteractiveTransition { /// Indicates transition direction. Must be set before each transition. var forward: Bool = true /// Current navigation controller used for transition. Must be set before transition starts var nc: UINavigationController? /** * Hack #1 with UINavigationController here */ override func cancel() { super.cancel() if forward { self.nc?.setNavigationBarHidden(false, animated: false) } self.nc?.setNavigationBarHidden(forward, animated: false) } } 
  • 在每个视图控制器(A,B,C)中,我做了以下的攻击:

     override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Hide and immediately show navigation bar: this will restore it's correct state self.navigationController?.setNavigationBarHidden(true, animated: false) self.navigationController?.setNavigationBarHidden(false, animated: true) } 

最好的解决scheme可能是C的模态全屏演示,但在我的情况下,我正在处理一个项目已经损坏的导航层次结构,我没有时间来正确地修复它。 基本上这就是我面对这个问题的原因。