![](/img/trans.png)
[英]how to perform segue from root view controller to the last view controller in the navigation stack in swift?
[英]interactivePopGestureRecognizer corrupts navigation stack on root view controller
在我的UINavigationController
中,我添加了自定義后退按鈕,其副作用是無法再從左向右滑動以彈出視圖控制器並向后導航。
所以我在我的自定義UINavigationController
類中實現了interactivePopGestureRecognizer
:
class UINavigationControllerExtended: UINavigationController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
if self.respondsToSelector(Selector("interactivePopGestureRecognizer")) {
self.interactivePopGestureRecognizer?.delegate = self
}
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailByGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return gestureRecognizer.isKindOfClass(UIScreenEdgePanGestureRecognizer)
}
}
這工作正常,除非我在我的根視圖控制器 (RVC) 中,它是一個UICollectionViewController
,即導航堆棧中最底部的視圖控制器。 當我做從左向右滑動的手勢時,似乎沒有發生任何事情,正如預期的那樣。 但是,當我隨后點擊 UICollectionViewCell 時,目標視圖控制器 (DVC) 不會被推到 RVC 上。 相反,我只在屏幕右側看到 DVC 的影子。
RVC 不再響應,但當我再次從左向右滑動時,DVC 交互地從右向左移動到屏幕中。 當我完成手勢時,DVC 完全移入屏幕,然后再次從左到右快速消失。 RVC 再次響應。
所以看起來 DVC 被推到導航堆棧上但沒有明顯地進入屏幕。
這種奇怪行為的起源有什么建議嗎?
為您的導航控制器實施UINavigationControllerDelegate
並在那里啟用/禁用手勢識別器。
// Fix bug when pop gesture is enabled for the root controller
func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
self.interactivePopGestureRecognizer?.enabled = self.viewControllers.count > 1
}
保持代碼獨立於推送的視圖控制器。
我當前的解決方案是在根視圖控制器中禁用interactivePopGestureRecognizer
:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.navigationController?.interactivePopGestureRecognizer?.enabled = false
}
在第一個子視圖控制器中,我再次啟用它。 但這似乎更像是一種解決方法,因為我不明白為什么導航堆棧一開始就搞砸了的實際問題。
這是我的解決方案。 斯威夫特 4.2
實施UIGestureRecognizerDelegate
和UINavigationControllerDelegate
協議。 在我的例子中,我在UITabBarController
中執行了此操作,它也是我的根視圖控制器。
然后,在 viewDidLoad 上執行:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
self.navigationController?.delegate = self
}
然后,為UINavigationControllerDelegate
添加委托方法,並通過計算導航控制器上的視圖數量來檢查它是否是根視圖,如果是則禁用它,如果不是則啟用它。
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
let enable = self.navigationController?.viewControllers.count ?? 0 > 1
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = enable
}
最后,添加UIGestureRecognizerDelegate
方法
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
這應該可以解決問題,而無需在項目的每個視圖中手動啟用/禁用手勢識別器。
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
self.interactivePopGestureRecognizer?.isEnabled = self.viewControllers.count > 1
}
更新了 Swift 5 的@rivera 解決方案
Guilherme Carvalho的解決方案對我有用,但我必須在viewWillAppear
中分配委托方法,在viewDidLoad
中對我的實現來說為時已晚。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.interactivePopGestureRecognizer?.delegate = self
navigationController?.delegate = self
}
試試這個代碼
func navigationController(navigationController: UINavigationController, didShowViewController vc: UIViewController, animated: Bool) {
self.interactivePopGestureRecognizer?.enabled = self.vc.count > 1
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.