1. 程式人生 > >iOS開發之自定義導航欄返回按鈕右滑返回手勢失效的解決

iOS開發之自定義導航欄返回按鈕右滑返回手勢失效的解決

我相信針對每一個iOS開發者來說~除了根檢視控制器外~所有的介面通過導航欄push過去的介面都是可以通過右滑來返回上一個介面~其實~在很多應用和APP中~使用者已經習慣了這個功能~然而~作為開發者的我們~也並沒有為此做些什麼~因為我們在建立專案時~蘋果公司已經為我們都做好了~那麼~我們這期就來聊一聊這系統自帶的右滑方法以及如何修改和攔截這個不被重視的方法~

什麼時候會被攔截

當我們使用程式碼或者用storyboard來建立一個新的控制器的時候~我們很少注意導航欄的leftItem~因為正常情況下~push到下一個介面的leftItem就是上一個介面的self.title~並且它也就是一個返回的功能~所以~我們很少去在意這些~但當我們有些需求~需要自定義leftItem的時候~那麼問題就來了~

  • 問題一:怎麼自定義leftItem
  • 問題二:為什麼系統自帶的右滑返回手勢失效
  • 問題三:怎麼解決這個失效問題

1.怎麼自定義leftItem

其實~這個東西嘛~說簡單也是很簡單的~因為~我們很明確的知道~左導航欄就一個功能~那就是返回上一個介面~很顯然~是需要使用者互動的~必用按鈕~
說多了都是廢話~直接上程式碼~
//自定義一個按鈕
UIButton *leftBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [leftBtn setTitle:@"返回" forState:UIControlStateNormal];[leftBtn addTarget:self action:@selector(backLastView) forControlEvents:UIControlEventTouchUpInside];leftBtn.frame = CGRectMake(0, 0, 60, 40);[leftBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];//將leftItem設定為自定義按鈕UIBarButtonItem *leftItem =[[UIBarButtonItem alloc]initWithCustomView: leftBtn];self.navigationItem.leftBarButtonItem = leftItem;


//按鈕點選事件 返回上一個介面
- (void)backLastView{ [self.navigationController popViewControllerAnimated:YES];}

需要注意的是~xcode自動從6.0之後~leftItem距左螢幕邊距有16個畫素點~這樣會導致在視覺上會感覺有點偏右~不算美觀~然而對於大多數處女座的程式設計師來說~這明顯是不能讓人去接受的~解決辦法有很多~在這裡提供一個最為方便的方法~設定一下按鈕的contentEdgeInsets(文字)imageEdgeInsets(圖片)屬性即可~如:leftButton.contentEdgeInsets = UIEdgeInsetsMake(0, -16, 0, 0);

3.怎麼解決這個失效問題
其實很簡單很簡單~只需要新增下面這一句程式碼即可
self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;

其實到這裡~問題應該都解決了~但是~畢竟右滑返回手勢只能靠近螢幕左邊緣才能使用~我們如何通過呼叫系統方法來實現在整個螢幕右滑就可以實現返回功能呢~
setp1:需要獲取系統自帶滑動手勢的target物件
id target = self.navigationController.interactivePopGestureRecognizer.delegate;
setp2:建立全屏滑動手勢~呼叫系統自帶滑動手勢的target的action方法
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];
step3:設定手勢代理~攔截手勢觸發
pan.delegate = self;
step4:別忘了~給導航控制器的view新增全屏滑動手勢
[self.view addGestureRecognizer:pan];
step5:將系統自帶的滑動手勢禁用
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
steo6:還記得剛剛設定的代理嗎?下面方法什麼時候呼叫?在每次觸發手勢之前都會詢問下代理,是否觸發。
這個方法就是攔截手勢觸發的方法.
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{}
return NO;則不需要觸發滑動手勢
return YES;則需要觸發滑動手勢