這似乎是一個已知的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)
}
}
}
我也試着設置導航欄授人以自我但它打破導航過程導致視圖控制器不被彈出。