背景
使用leftBarButtonItem
实现自定义返回按钮,从而导致侧滑返回失效。
为了解决侧滑返回失效的问题,在UIViewController中执行,
navigationController?.interactivePopGestureRecognizer?.delegate = self
侧滑问题解决,
目前的层级结构为,UINavigationController
中包含一个或多个UIViewController
Bug复现
- 进入
UINavigationController
的rootViewController
- 执行侧滑手势
- 点击按钮,该按钮执行push操作
- 画面卡住
解决方案
最终使用这个解决方案,如下
extension UINavigationController:UINavigationControllerDelegate {
open override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
if responds(to: #selector(getter: self.interactivePopGestureRecognizer)) {
if viewControllers.count > 1 {
interactivePopGestureRecognizer?.isEnabled = true
} else {
interactivePopGestureRecognizer?.isEnabled = false
}
}
}
}
过程与思考
在最终确定解决方案之前,我做了一个尝试,试图理解这个问题,
当在UIViewController
中执行如下代码时,
navigationController?.interactivePopGestureRecognizer?.delegate = nil
可以侧滑,bug依然存在。可以猜想,将delegate
置为self
和nil
,都是一样的。可能是interactivePopGestureRecognizer有默认实现,这个默认实现能够完成侧滑功能,但是没有处理rootViewController
的情况。
其他解决方案
当然,还有另一种解决思路,
var originDelegate: UIGestureRecognizerDelegate?
// replace
originDelegate = interactivePopGestureRecognizer?.delegate
interactivePopGestureRecognizer?.delegate = self
// restore later
interactivePopGestureRecognizer?.delegate = originDelegate