說明:
UINavigationController默認在push出的控制器中都有邊沿滑動返回功能,但是只能從屏幕左邊滑才能返回,若從屏幕中間畫並沒有效果。下面實現全屏滑動功能。
探究:
系統默認能夠實現滑動返回是因為UINavigationController具有interactivePopGestureRecognizer,所以我們可以使用NSLog打印出它的全部信息如下
<UIScreenEdgePanGestureRecognizer: 0x7fdf4a431c70; state = Possible; enabled = NO; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7fdf4a791830>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fdf4a4314e0>)>>
從打印信息可以看出
- interactivePopGestureRecognizer的真實類型為UIScreenEdgePanGestureRecognizer(屏幕邊沿手勢)
- 手勢調用的方法為handleNavigationTransition:
- 手勢的Target對象的類型為_UINavigationInteractiveTransition
實現思想:
給UINavigationController的view添加滑動手勢pan,替換掉系統的手勢,並在觸發pan手勢時調用系統的方法。
實現難點:
- 系統手勢調用方法,(通過打印信息以獲得)
- target對象 通過加斷點調試查看系統手勢的target和系統手勢的代理發現他們的類型和地址都相同,說明系統手勢的代理即為系統手勢的target。
實現代碼:
- (void)viewDidLoad { [super viewDidLoad]; // 獲取系統手勢的target對象 id tagart = self.interactivePopGestureRecognizer.delegate; // 創建手勢調用系統的方法 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget: tagart action:@selector(handleNavigationTransition:)]; // 添加手勢 [self.view addGestureRecognizer:pan]; // 設置手勢的代理 pan.delegate = self; // 禁能系統的手勢 self.interactivePopGestureRecognizer.enabled = NO; } // 手勢的代理方法 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { // 非根控制器使能手勢 return self.childViewControllers.count > 1; }
注意點:
在手勢的代理方法中要判斷是否是跟控制器,如果是根控制器要禁能手勢
- 因為手勢會觸發滑動返回,若是根控制器則無法返回,就會出現假死的bug