背景介紹 : 在開發(fā)過程中,系統(tǒng)自帶的某些功能,可能不滿足我們的開發(fā)需求,所以常常需要我們自定義.當我們自定義導(dǎo)航條上的返回按鈕之后,會發(fā)現(xiàn)系統(tǒng)自帶的滑動返回手勢處于失效狀態(tài),這是本章主要想解決的問題.
思路 : 既然自定義了導(dǎo)航條上的返回按鈕,手勢失效,說明系統(tǒng)內(nèi)部是遵守了手勢代理的,我們只需要打印出系統(tǒng)自帶的手勢就可以設(shè)置了.
// 打印系統(tǒng)自帶的手勢
NSLog(@"%@",self.interactivePopGestureRecognizer);
// 打印結(jié)果
<UIScreenEdgePanGestureRecognizer: 0x7fb18a627ce0;
state = Possible; delaysTouchesBegan = YES;
view = <UILayoutContainerView 0x7fb18a626210>;
target= <(action=handleNavigationTransition:,
target=<_UINavigationInteractiveTransition 0x7fb18a627a00>)>
- 注意 : 在打印結(jié)果中,系統(tǒng)自帶的手勢只支持邊緣滑動手勢,它用的是 UIScreenEdgePanGestureRecognizer手勢,只能在控制器的邊緣才能出發(fā)手勢的方法,這樣,我們改一下,改成全屏都能出發(fā)滑動返回功能.
- 我們來解讀一下這個打印結(jié)果 :
- 只要觸發(fā)了UIScreenEdgePanGestureRecognizer這個手勢,就會調(diào)用_UINavigationInteractiveTransition代理的
只要觸發(fā)UIScreenEdgePanGestureRecognizer,就會調(diào)用_UINavigationInteractiveTransition代理的
handleNavigationTransition這個方法.
說明 : _UINavigationInteractiveTransition代理的這個
handleNavigationTransition方法有滑動返回的功能,只要我們創(chuàng)建新的手勢設(shè)置這個代理,實現(xiàn)這個方法就可以實現(xiàn)滑動返回的功能了, - 下面我們照葫蘆畫瓢,實現(xiàn)全屏滑動返回.
- 全屏滑動返回手勢: UIPanGestureRecognizer
- 代理: _UINavigationInteractiveTransition
- 代理方法:handleNavigationTransition: (注意代理方法有參數(shù),記得不要遺漏了冒號)
- (void)viewDidLoad {
[super viewDidLoad];
// 設(shè)置代理
id target = self.interactivePopGestureRecognizer.delegate;
// 創(chuàng)建手勢
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];
// 設(shè)置pan手勢的代理
pan.delegate = self;
// 添加手勢
[self.view addGestureRecognizer:pan];
// 將系統(tǒng)自帶的手勢覆蓋掉
self.interactivePopGestureRecognizer.enabled = NO;
}
注意了 : 這里一定要設(shè)置pan.delegate = self, 不然程序會有假死的狀況.(本章重點)
做到這里,可以運行模擬器試一下, 會驚奇的發(fā)現(xiàn),能全屏滑動返回了,但是,回到根控制器后,還是能繼續(xù)滑動,這不是我們的想要的效果.所以還需要調(diào)用手勢代理中的一個方法:即是否允許接收觸摸事件.
// 表示的意思是:當擋墻控制器是根控制器了,那么就不接收觸摸事件,只有當不是根控制器時才需要接收事件.
#pragma mark - UIGestureRecognizerDelegate
// 是否觸發(fā)手勢
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
return self.childViewControllers.count > 1;
}
- 總結(jié): 手勢代理中還有很多好用的方法,比如: 是否允許同時接收多個手勢事件等方法,都是開發(fā)中常用的,可以自己去手勢代理的頭文件中自學(xué).