現象描述
實際開發過程中,難免會重寫UINavigationController的左返回按鈕,然后就導致了系統默認的右滑返回失效。
如何處理
直接先上關鍵代碼:
public class DZBaseNavigationController: UINavigationController {
public override func viewDidLoad()
{
super.viewDidLoad()
//處理右滑返回手勢
let selector = NSSelectorFromString("interactivePopGestureRecognizer")
if self.responds(to: selector){
self.interactivePopGestureRecognizer?.delegate = self
self.delegate = self
}
}
//重寫父類方法
public override func pushViewController(_ viewController: UIViewController, animated: Bool)
{
//處理右滑返回手勢
let selector = NSSelectorFromString("interactivePopGestureRecognizer")
if self.responds(to: selector){
self.interactivePopGestureRecognizer?.isEnabled = false
}
super.pushViewController(viewController, animated: animated)
}
}
extension DZBaseNavigationController:UINavigationControllerDelegate,UIGestureRecognizerDelegate{
//處理右滑返回手勢
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return true
}
//DZBaseViewController為項目中所有UIViewController的子類,也就是目前項目中所有的UIViewController都是用的DZBaseViewController,DZBaseViewController里可以添加一些基礎屬性,比如: ///是否能右滑返回 var isCanGestureBack:Bool = true
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
let selector = NSSelectorFromString("interactivePopGestureRecognizer")
let currentvc = self.topViewController
if self.responds(to: selector){
if gestureRecognizer == self.interactivePopGestureRecognizer{
if self.viewControllers.count == 1{
return false
}else{
if let vc = currentvc as? DZBaseViewController{
if vc.isCanGestureBack == false{
return false
}else{
return true
}
}else{
return false
}
}
}
}
return false
}
public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
let selector = NSSelectorFromString("interactivePopGestureRecognizer")
if self.responds(to: selector){
self.interactivePopGestureRecognizer?.isEnabled = true;
}
}
}
備注:
關鍵字為:
interactivePopGestureRecognizer
所有的邏輯都在DZBaseNavigationController里,DZBaseViewController繼承UIViewController,isCanGestureBack參數可以在具體某個不需要手勢右滑返回的UIViewController中設置為:false
class DZBaseViewController: UIViewController {
///是否能右滑返回
var isCanGestureBack:Bool = true
}
比如某個UIViewController不需要支持右滑返回:
class DZPasswordLoginVC: DZBaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.isCanGestureBack = false
}
}