您可以使用setViewControllers(_:animated:)
重新排列視圖控制器堆棧。您無需做任何特殊的操作即可使後退按鈕正常工作。導航控制器根據其viewControllers
陣列中的第二項(如果存在第二項)設置後退按鈕,並在更新viewControllers
陣列時更新後退按鈕。
下面是我該如何做到這一點。首先,我們添加一個方法到UIViewController
,詢問它是否是特定的userId
的視圖控制器。由於大多數視圖控制器都沒有(也不可能是)正確的視圖控制器,它只是返回false
:
extension UIViewController {
func isViewControllerForUserId(userId: Int) -> Bool {
return false
}
}
然後我們在MessagesViewController
重寫此方法來返回true
在適當的時候:
extension MessagesViewController {
override func isViewControllerForUserId(userId: Int) -> Bool {
return self.userId == userId
}
}
現在,爲了顯示特定用戶的視圖控制器,我們在導航控制器的堆棧中搜索現有的視圖控制器。我們採取的行動取決於我們是否找到它:
func showMessageForUserId(userId: Int) {
if let index = navController.viewControllers.indexOf({ $0.isViewControllerForUserId(userId) }) {
navController.moveToTopOfNavigationStack(viewControllerAtIndex: index)
} else {
pushNewViewControllerForUserId(userId)
}
}
如果我們沒有發現它,我們做一個新的視圖控制器推:
private func pushNewViewControllerForUserId(userId: Int) {
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
vc.userId = userId
self.navController.pushViewController(vc, animated: true)
}
如果我們沒有發現它,我們它用這種方法移動到導航堆棧的頂部:
extension UINavigationController {
func moveToTopOfNavigationStack(viewControllerAtIndex index: Int) {
var stack = viewControllers
if index == stack.count - 1 {
// nothing to do because it's already on top
return
}
let vc = stack.removeAtIndex(index)
if (reorderingIsBuggy) {
setViewControllers(stack, animated: false)
}
stack.append(vc)
setViewControllers(stack, animated: true)
}
private var reorderingIsBuggy: Bool {
// As of iOS 9.3 beta 3, `UINavigationController` drops the prior top-of-stack
// when you use `setViewControllers(_:animated:)` to move a lower item to the
// top with animation. The workaround is to remove the lower item from the stack
// without animation, then add it to the top of the stack with animation. This
// makes it display a push animation instead of a pop animation and avoids
// dropping the prior top-of-stack.
return true
}
}
感謝羅布。我在索引處刪除它並將其附加後打印出堆棧。它以正確的順序打印,所以看起來很好。當我調用'''setViewControllers'''時,一切似乎都很好,並且希望VC顯示在頂部。然而,VC在獲得''deinit'''之前就消失了。你知道爲什麼以前的VC消失嗎? (我只在2個VC上進行測試) – TIMEX
注意:我改變了這一行:'''navController.setViewControllers(stack,animated:false)'''爲animated:false,並且全部似乎都正常工作。任何想法爲什麼做這個改變解決了這個問題? – TIMEX
哪個視圖控制器運行'deinit'? –