自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

iOS系統(tǒng)右滑返回全局控制方案

移動(dòng)開(kāi)發(fā) iOS
今天有個(gè)小需求,在點(diǎn)擊導(dǎo)航條上的返回按鈕之前要調(diào)用某個(gè)API,并彈出UIAlertView來(lái)顯示,根據(jù)用戶的選項(xiàng)判斷是否是返回還是繼續(xù)留在當(dāng)前控制器。舉個(gè)簡(jiǎn)單的例子,當(dāng)點(diǎn)擊導(dǎo)航條上的左上角返回按鈕時(shí),就調(diào)用我們的API來(lái)提示是否知道,點(diǎn)擊知道則返回,點(diǎn)擊不知道則繼續(xù)留在當(dāng)前控制器。

前言

今天有個(gè)小需求,在點(diǎn)擊導(dǎo)航條上的返回按鈕之前要調(diào)用某個(gè)API,并彈出UIAlertView來(lái)顯示,根據(jù)用戶的選項(xiàng)判斷是否是返回還是繼續(xù)留在當(dāng)前控制器。舉個(gè)簡(jiǎn)單的例子,當(dāng)點(diǎn)擊導(dǎo)航條上的左上角返回按鈕時(shí),就調(diào)用我們的API來(lái)提示是否知道,點(diǎn)擊知道則返回,點(diǎn)擊不知道則繼續(xù)留在當(dāng)前控制器。

那么問(wèn)題來(lái)了,導(dǎo)航自帶的右滑返回手勢(shì)在點(diǎn)擊系統(tǒng)的返回按鈕時(shí),不會(huì)沒(méi)有辦法處理,那是自動(dòng)的,因此就要想辦法改成leftBarButtonItem了,但是使用了leftBarButtonItem就沒(méi)有了右滑返回手勢(shì)。

魚(yú)和熊掌不可兼得?筆者自有辦法!

筆者嘗試寫(xiě)個(gè)demo來(lái)驗(yàn)證有什么辦法可以解決,嘗試了以下四種:

  • 只在當(dāng)前controller遵守UIGestureRecognizerDelegate并設(shè)置代理為self
  • 將UIGestureRecognizerDelegate放在公共基類控制器遵守并設(shè)置代理為self,然后子類重寫(xiě)代理方法
  • 將UIGestureRecognizerDelegate放在公共導(dǎo)航類HYBNavigationController里遵守,并設(shè)置代理為導(dǎo)航類,然后重寫(xiě)push/pop相關(guān)的所有方法
  • 將UIGestureRecognizerDelegate放在公共導(dǎo)航類HYBNavigationController里遵守,并設(shè)置代理為導(dǎo)航類,但是,只遵守-gestureRecognizerShouldBegin:代理方法

方案一(不可行)

方案一:只在當(dāng)前controller遵守UIGestureRecognizerDelegate并設(shè)置代理為self

為什么不可行呢?當(dāng)想不測(cè)試怎么知道呢?光想是很難考慮全面的。于是寫(xiě)了個(gè)小demo來(lái)測(cè)試。

我們?cè)谠揷ontroller里這樣寫(xiě):

  1. - (void)viewDidLoad { 
  2.  
  3.   [super viewDidLoad]; 
  4.  
  5.   
  6.  
  7.     UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
  8.  
  9.   [button setTitle:@"返回" forState:UIControlStateNormal]; 
  10.  
  11.   [button addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside]; 
  12.  
  13.   [button sizeToFit]; 
  14.  
  15.   [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 
  16.  
  17.   UIBarButtonItem *btnItem = [[UIBarButtonItem alloc] initWithCustomView:button]; 
  18.  
  19.   self.navigationItem.leftBarButtonItem = btnItem; 
  20.  
  21.   
  22.  
  23.   // 關(guān)鍵行 
  24.  
  25.   self.navigationController.interactivePopGestureRecognizer.delegate = self; 
  26.  
  27.  

一旦設(shè)置了代理為self,那么使用leftBarButtonItem后就可以實(shí)現(xiàn)點(diǎn)擊回調(diào),而且右滑手勢(shì)還在。

但是,self.navigationController那可是導(dǎo)航控制器對(duì)象的的代理被修改當(dāng)某個(gè)控制器對(duì)象了,當(dāng)這個(gè)控制器類被釋放后,那么代理就為nil了,如此就再也沒(méi)有右滑返回手勢(shì)了。

那么可能有人會(huì)想,在-viewDidAppear:里設(shè)置代理為self,在-viewDidDisappear:時(shí)設(shè)置代理成原來(lái)的代理對(duì)象呢?同樣不可以。當(dāng)A push到B,B push到C,然后從C返回后,代理就不再是最初的導(dǎo)航代理了。

所以,該方案不可行。

方案二(不可行)

方案二:將UIGestureRecognizerDelegate放在公共基類控制器遵守并設(shè)置代理為self,然后子類重寫(xiě)代理方法

筆者嘗試將UIGestureRecognizerDelegate放在HYBBaseViewControlle里遵守,然后實(shí)現(xiàn)代理,默認(rèn)返回YES,表示支持右滑返回。如果要讓某個(gè)控制器不支持右滑返回或者在返回前先執(zhí)行什么操作,可以通過(guò)重寫(xiě)此代理方法來(lái)實(shí)現(xiàn)。

當(dāng)只在一個(gè)控制器里時(shí),這是可以實(shí)現(xiàn)的。但是,當(dāng)這個(gè)控制器被釋放了以后,代理對(duì)象就變成了nil了,因此代理是對(duì)于導(dǎo)航條對(duì)象的,不屬性單個(gè)控制器的。

方案三(可行,但復(fù)雜)

方案三:將UIGestureRecognizerDelegate放在公共導(dǎo)航類HYBNavigationController里遵守,并設(shè)置代理為導(dǎo)航類,然后重寫(xiě)push/pop相關(guān)的所有方法。

如實(shí)現(xiàn)如何下:

  1. //  HYBNavigationController.m 
  2.  
  3. //  NavRightPanGestureDemo 
  4.  
  5. // 
  6.  
  7. //  Created by huangyibiao on 16/2/22. 
  8.  
  9. //  Copyright © 2016年 huangyibiao. All rights reserved. 
  10.  
  11. // 
  12.  
  13.   
  14.  
  15. #import "HYBNavigationController.h" 
  16.  
  17. #import "HYBBaseViewController.h" 
  18.  
  19.   
  20.  
  21. @interface HYBNavigationController () 
  22.  
  23.   
  24.  
  25. @property (nonatomic, assign) BOOL enableRightGesture; 
  26.  
  27.   
  28.  
  29. @end 
  30.  
  31.   
  32.  
  33. @implementation HYBNavigationController 
  34.  
  35.   
  36.  
  37. - (void)viewDidLoad { 
  38.  
  39.   [super viewDidLoad]; 
  40.  
  41.   
  42.  
  43.   self.enableRightGesture = YES; 
  44.  
  45.   self.interactivePopGestureRecognizer.delegate = self; 
  46.  
  47.  
  48.   
  49.  
  50. - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { 
  51.  
  52.   return self.enableRightGesture; 
  53.  
  54.  
  55.   
  56.  
  57. - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { 
  58.  
  59.   if ([viewController isKindOfClass:[HYBBaseViewController class]]) { 
  60.  
  61.     if ([viewController respondsToSelector:@selector(gestureRecognizerShouldBegin)]) { 
  62.  
  63.       HYBBaseViewController *vc = (HYBBaseViewController *)viewController; 
  64.  
  65.       self.enableRightGesture = [vc gestureRecognizerShouldBegin]; 
  66.  
  67.     } 
  68.  
  69.   } 
  70.  
  71.   
  72.  
  73.   [super pushViewController:viewController animated:YES]; 
  74.  
  75.  
  76.   
  77.  
  78. - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated { 
  79.  
  80.      self.enableRightGesture = YES; 
  81.  
  82.   return [super popToRootViewControllerAnimated:animated]; 
  83.  
  84.  
  85.   
  86.  
  87. - (UIViewController *)popViewControllerAnimated:(BOOL)animated { 
  88.  
  89.   if (self.viewControllers.count == 1) { 
  90.  
  91.     self.enableRightGesture = YES; 
  92.  
  93.   } else { 
  94.  
  95.     NSUInteger index = self.viewControllers.count - 2; 
  96.  
  97.     UIViewController *destinationController = [self.viewControllers objectAtIndex:index]; 
  98.  
  99.     if ([destinationController isKindOfClass:[HYBBaseViewController class]]) { 
  100.  
  101.       if ([destinationController respondsToSelector:@selector(gestureRecognizerShouldBegin)]) { 
  102.  
  103.         HYBBaseViewController *vc = (HYBBaseViewController *)destinationController; 
  104.  
  105.         self.enableRightGesture = [vc gestureRecognizerShouldBegin]; 
  106.  
  107.       } 
  108.  
  109.     } 
  110.  
  111.   } 
  112.  
  113.   
  114.  
  115.   return [super popViewControllerAnimated:animated]; 
  116.  
  117.  
  118.   
  119.  
  120. - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated { 
  121.  
  122.   if (self.viewControllers.count == 1) { 
  123.  
  124.     self.enableRightGesture = YES; 
  125.  
  126.   } else { 
  127.  
  128.     UIViewController *destinationController = viewController; 
  129.  
  130.     if ([destinationController isKindOfClass:[HYBBaseViewController class]]) { 
  131.  
  132.       if ([destinationController respondsToSelector:@selector(gestureRecognizerShouldBegin)]) { 
  133.  
  134.         HYBBaseViewController *vc = (HYBBaseViewController *)destinationController; 
  135.  
  136.         self.enableRightGesture = [vc gestureRecognizerShouldBegin]; 
  137.  
  138.       } 
  139.  
  140.     } 
  141.  
  142.   } 
  143.  
  144.   
  145.  
  146.   return [super popToViewController:viewController animated:animated]; 
  147.  
  148.  
  149.   
  150.  
  151. @end  

這是通過(guò)重寫(xiě)所有的pop/push相關(guān)方法,通過(guò)判斷是否要求支持右滑來(lái)設(shè)置。然后,我們要讓某個(gè)控制器類在右滑返回或者點(diǎn)擊返回之前,先調(diào)用我們的API判斷,如下:

  1. #import "HYBBController.h" 
  2.  
  3.   
  4.  
  5. @implementation HYBBController 
  6.  
  7.   
  8.  
  9. - (void)viewDidLoad { 
  10.  
  11.   [super viewDidLoad]; 
  12.  
  13.   
  14.  
  15.   UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
  16.  
  17.   [button setTitle:@"返回" forState:UIControlStateNormal]; 
  18.  
  19.   [button addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside]; 
  20.  
  21.   [button sizeToFit]; 
  22.  
  23.   [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 
  24.  
  25.   UIBarButtonItem *btnItem = [[UIBarButtonItem alloc] initWithCustomView:button]; 
  26.  
  27.   self.navigationItem.leftBarButtonItem = btnItem; 
  28.  
  29.  
  30.   
  31.  
  32. - (BOOL)gestureRecognizerShouldBegin { 
  33.  
  34.   [self onBack]; 
  35.  
  36.   return NO
  37.  
  38.  
  39.   
  40.  
  41. - (void)onBack { 
  42.  
  43.   UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"標(biāo)哥的技術(shù)博客" 
  44.  
  45.                                                       message:@"知道博客地址是什么嗎?" 
  46.  
  47.                                                      delegate:self 
  48.  
  49.                                             cancelButtonTitle:@"不知道" 
  50.  
  51.                                             otherButtonTitles:@"知道", nil]; 
  52.  
  53.   [alertView show]; 
  54.  
  55.  
  56.   
  57.  
  58. #pragma mark - UIAlertViewDelegate 
  59.  
  60. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 
  61.  
  62.   if (buttonIndex == 0) { 
  63.  
  64.   
  65.  
  66.   } else { 
  67.  
  68.     if ([self.navigationItem.title isEqualToString:@"VC6"]) { 
  69.  
  70.       NSUInteger index = self.navigationController.viewControllers.count - 3; 
  71.  
  72.       UIViewController *vc = [self.navigationController.viewControllers objectAtIndex:index]; 
  73.  
  74.       [self.navigationController popToViewController:vc animated:YES]; 
  75.  
  76.     } else { 
  77.  
  78.       [self.navigationController popViewControllerAnimated:YES]; 
  79.  
  80.     } 
  81.  
  82.   } 
  83.  
  84.  
  85.   
  86.  
  87. @end  

這種方案確實(shí)實(shí)現(xiàn)了我們的需求。但是,有沒(méi)有更簡(jiǎn)單的方案呢?今天可能是眼睛有點(diǎn)困的原因,在研究的時(shí)候沒(méi)有意識(shí)到第四種方案。在我準(zhǔn)備寫(xiě)這篇文章的時(shí)候,我再認(rèn)識(shí)地理了一遍邏輯,發(fā)現(xiàn)還有非常簡(jiǎn)單的一種方案可以實(shí)現(xiàn)我的需求。

方案四(可靠,***)

方案四:將UIGestureRecognizerDelegate放在公共導(dǎo)航類HYBNavigationController里遵守,并設(shè)置代理為導(dǎo)航類,但是,只遵守-gestureRecognizerShouldBegin:代理方法。

  1. @interface HYBNavigationController () 
  2.  
  3.   
  4.  
  5. @end 
  6.  
  7.   
  8.  
  9. @implementation HYBNavigationController 
  10.  
  11.   
  12.  
  13. - (void)viewDidLoad { 
  14.  
  15.   [super viewDidLoad]; 
  16.  
  17.   
  18.  
  19.   self.interactivePopGestureRecognizer.delegate = self; 
  20.  
  21.  
  22.   
  23.  
  24. - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { 
  25.  
  26.   BOOL ok = YES; // 默認(rèn)為支持右滑反回 
  27.  
  28.   if ([self.topViewController isKindOfClass:[HYBBaseViewController class]]) { 
  29.  
  30.     if ([self.topViewController respondsToSelector:@selector(gestureRecognizerShouldBegin)]) { 
  31.  
  32.       HYBBaseViewController *vc = (HYBBaseViewController *)self.topViewController; 
  33.  
  34.      ok = [vc gestureRecognizerShouldBegin]; 
  35.  
  36.     } 
  37.  
  38.   } 
  39.  
  40.   
  41.  
  42.   return ok; 
  43.  
  44.  
  45.   
  46.  
  47. @end  

使用方法與第三種方案一樣,是不是非常地簡(jiǎn)化了?看來(lái)是元宵給我的禮物啊,突然想到這樣的辦法。以前一直沒(méi)有研究過(guò)interactivePopGestureRecognizer屬性,這個(gè)屬性是iOS7以后才有的,因此在項(xiàng)目中一直不能直接使用leftBarButtonItem處理,除非那個(gè)界面不要右滑返回。

現(xiàn)在,一切都明了了,想要使用leftBarButtonItem在公共基類控制器中統(tǒng)一調(diào)用API來(lái)設(shè)置就非常簡(jiǎn)單了,右滑返回手勢(shì)也可以正常使用~

還等什么,趕緊試試吧!

***

如果你所使用的項(xiàng)目也有這樣的需求,不防試試吧!筆者提供了demo的,因此可以先下載demo來(lái)看看效果哦!經(jīng)過(guò)多次測(cè)試,筆者認(rèn)為這是可行的方案,大家若在使用中出現(xiàn)問(wèn)題,還請(qǐng)反饋與筆者,我也想了解是什么情況,當(dāng)然也要找解決方案,共同進(jìn)步嘛。

責(zé)任編輯:龐桂玉 來(lái)源: iOS大全
相關(guān)推薦

2009-08-17 21:52:18

2014-09-24 11:52:37

微信企業(yè)號(hào)開(kāi)發(fā)

2010-04-23 00:03:18

全局負(fù)載均衡

2021-06-04 17:30:50

iOS導(dǎo)航欄方案

2015-02-11 15:06:41

微信SDK

2023-07-06 12:54:15

開(kāi)源KelemetryKubernetes

2013-07-25 15:15:26

iOS開(kāi)發(fā)學(xué)習(xí)iOS全局變量

2021-11-17 08:16:03

內(nèi)存控制Go

2013-09-25 14:47:15

遠(yuǎn)程控制SDK

2010-12-21 17:38:12

2021-04-20 14:57:20

架構(gòu)運(yùn)維技術(shù)

2013-10-14 18:37:57

2013-10-16 15:36:53

iOS優(yōu)化

2011-10-21 15:59:51

深信服負(fù)載均衡

2012-08-08 15:34:18

負(fù)載均衡深信服

2013-04-27 10:07:51

飛利浦

2021-06-21 10:52:49

華為AI

2021-06-16 10:21:19

華為智慧
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)