这似乎是一个已知的issue。
要解决这个问题,我最终实现了自定义的NavigationController,以便与NavigationBar配对使用。只要我可以看到只有pushViewController和popToRootViewController不按预期工作。所以,下面的代码覆盖了所有的导航的情况下适用于iOS 10.
NavigationBar.swift:
final class NavigationBar: UINavigationBar {
override func pushItem(_ item: UINavigationItem, animated: Bool) {
return transit(to: item, isNewItem: true, animated: animated) {
super.pushItem(item, animated: animated)
}
}
override func popItem(animated: Bool) -> UINavigationItem? {
return transit(to: backItem, isNewItem: false, animated: animated) {
super.popItem(animated: animated)
}
}
override func setItems(_ items: [UINavigationItem]?, animated: Bool) {
let isNewItem = items?.last
.flatMap {self.items?.contains($0)}
.map {!$0}
?? true
return transit(to: items?.last, isNewItem: isNewItem, animated: animated) {
super.setItems(items, animated: animated)
}
}
func transit<T>(to item: UINavigationItem?, isNewItem: Bool, animated: Bool, action:() -> T) -> T {
CATransaction.begin(); defer {CATransaction.commit()}
CATransaction.setDisableActions(!animated)
doSomeCoolAnimatedStuff(isNewItem)
return action()
}
}
NavigationController.swift:
final class NavigationController: UINavigationController {
private var baforeIos11: Bool {if #available(iOS 11.0, *) {return false} else {return true}}
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
guard let bar = navigationBar as? NavigationBar, baforeIos11 else {
return super.pushViewController(viewController, animated: animated)
}
return bar.transit(to: viewController.navigationItem, isNewItem: true, animated: true) {
super.pushViewController(viewController, animated: animated)
}
}
override func popToRootViewController(animated: Bool) -> [UIViewController]? {
guard let bar = navigationBar as? NavigationBar else {
return super.popToRootViewController(animated: animated)
}
return bar.transit(to: viewControllers.first?.navigationItem, isNewItem: false, animated: true) {
super.popToRootViewController(animated: animated)
}
}
}
我也试着设置导航栏授人以自我但它打破导航过程导致视图控制器不被弹出。