iOS 手勢(shì)問(wèn)題

右滑手勢(shì)返回##

原文
ios7開(kāi)始 蘋果增加了頁(yè)面 右滑返回的效果;具體的是以UINavigationController為容器的ViewController間右滑切換頁(yè)面词顾。
代碼里的設(shè)置是:

 self.navigationController.interactivePopGestureRecognizer.enabled = YES;(default is YES)

可以看到蘋果給navigationController添加了一個(gè)手勢(shì)(具體為UIScreenEdgePanGestureRecognizer(邊緣手勢(shì),同樣是ios7以后才有的))咒循,就是利用這個(gè)手勢(shì)實(shí)現(xiàn)的 ios7的側(cè)滑返回隅茎。

問(wèn)題1:然而事情并非我們想的那么簡(jiǎn)單欣孤。
1.當(dāng)我們用系統(tǒng)的UINavigationController,并且也是利用系統(tǒng)的navigateBar的時(shí)候呀潭,是完全沒(méi)有問(wèn)題的
2.但是當(dāng)我們沒(méi)有用系統(tǒng)的navigateBar或者自定義了返回按鈕的時(shí)候钉迷,這個(gè)時(shí)候 右滑返回是失效的。

解決(問(wèn)題1)辦法:對(duì)于這種失效的情況钠署,考慮到interactivePopGestureRecognizer也有delegate屬性糠聪,替換默認(rèn)的self.navigationController.interactivePopGestureRecognizer.delegate來(lái)配置右滑返回的表現(xiàn)也是可行的。
我們可以在主NavigationController中設(shè)置一下:

  self.navigationController.interactivePopGestureRecognizer.delegate =(id)self

問(wèn)題2
但是出現(xiàn)很多問(wèn)題踏幻,比如說(shuō)在rootViewController的時(shí)候這個(gè)手勢(shì)也可以響應(yīng)枷颊,導(dǎo)致整個(gè)程序頁(yè)面不響應(yīng);push了多層后该面,快速的觸發(fā)兩次手勢(shì)夭苗,也會(huì)錯(cuò)亂

解決(問(wèn)題2)辦法:

  @interface NavRootViewController : UINavigationController
    @property(nonatomic,weak) UIViewController* currentShowVC;
  @end
  @implementation NavRootViewController
  -(id)initWithRootViewController:(UIViewController *)rootViewController
  {
    NavRootViewController* nvc = [super initWithRootViewController:rootViewController];
    self.interactivePopGestureRecognizer.delegate = self;
    nvc.delegate = self;
    return nvc;
  }
  -(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
  }
  -(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
    if (navigationController.viewControllers.count == 1)
        self.currentShowVC = Nil;
    else
        self.currentShowVC = viewController;
  }
 -(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
      if (gestureRecognizer == self.interactivePopGestureRecognizer) {
          return (self.currentShowVC == self.topViewController); //the most important
      }
      return YES;
 }
 @end

問(wèn)題三:
UIScrollView上手勢(shì)失靈:經(jīng)研究,發(fā)現(xiàn)是UIScrollView上已經(jīng)添加了 panGestureRecognizer(滑動(dòng))手勢(shì)

【解決方案】

蘋果以UIGestureRecognizerDelegate的形式隔缀,支持多個(gè)UIGestureRecognizer共存题造。其中的一個(gè)方法是:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
一句話總結(jié)就是此方法返回YES時(shí),手勢(shì)事件會(huì)一直往下傳遞猾瘸,不論當(dāng)前層次是否對(duì)該事件進(jìn)行響應(yīng)界赔。

  @implementation UIScrollView (AllowPanGestureEventPass)
  - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ 
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]){
         return YES;    
    }else {
         return  NO;    
    }
  }

這種方式就是建一個(gè)UISCrollVIew的category,然后我用的時(shí)候是全局用的牵触,不知道為什么在快速返回上一層的時(shí)候并快速點(diǎn)擊會(huì)照成線程卡死淮悼。 還有就是兩個(gè)手勢(shì)共存,所以在返回上一層的過(guò)程中揽思,UIScrollerView還會(huì)滾動(dòng)

事實(shí)上袜腥,對(duì)UIGestureRecognizer來(lái)說(shuō),它們對(duì)事件的接收順序和對(duì)事件的響應(yīng)是可以分開(kāi)設(shè)置的钉汗,即存在接收鏈和響應(yīng)鏈羹令。接收鏈如上文所述,和UIView綁定损痰,由UIView的層次決定接收順序福侈。
而響應(yīng)鏈在apple君的定義下,邏輯出奇的簡(jiǎn)單卢未,只有一個(gè)方法可以設(shè)置多個(gè)gestureRecognizer的響應(yīng)關(guān)系:

 - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;


  //從UINavigationController里得到這個(gè)邊緣手勢(shì)
  @implementation UINavigationController (iOS7Support)
  @dynamic screenEdgePanGestureRecognizer;

  - (UIScreenEdgePanGestureRecognizer *)screenEdgePanGestureRecognizer{
       UIScreenEdgePanGestureRecognizer *screenEdgePanGestureRecognizer = nil;
       if (self.view.gestureRecognizers.count > 0){
           for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers){
               if ([recognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]){
                   screenEdgePanGestureRecognizer = (UIScreenEdgePanGestureRecognizer *)recognizer;
                break;
               }
           }
       }
       return screenEdgePanGestureRecognizer;
  }
  @end
 

 //當(dāng)screenEdgePanGestureRecognizer生效時(shí)肪凛,UIScrollerView的panGestureRecognizer失效堰汉,這樣就解決了沖突
 UIScreenEdgePanGestureRecognizer *screenEdgePanGestureRecognizer = self.navigationController.screenEdgePanGestureRecognizer;
 [_scrollerView.panGestureRecognizer requireGestureRecognizerToFail:screenEdgePanGestureRecognizer];

全屏的右滑返回##

FDFullscreenPopGesture這個(gè)開(kāi)源項(xiàng)目里用運(yùn)行時(shí)很簡(jiǎn)單的實(shí)現(xiàn)了全屏的右滑返回。

有人說(shuō)直接用下面這種kvo的方式就能實(shí)現(xiàn)了显拜,這是系統(tǒng)原有的私有屬性衡奥,增大那個(gè)響應(yīng)區(qū)域就可以了。但我自己還沒(méi)實(shí)測(cè)過(guò)远荠,有興趣的可以試試矮固。

[self.interactivePopGestureRecognizer setValue:@([UIScreen mainScreen].bounds.size.width) forKeyPath:@"_recognizer._settings._edgeSettings._edgeRegionSize"];

touchesbegan未響應(yīng)##

touchesbegan跟UITapGestureRecognizer同時(shí)存在時(shí),tap會(huì)有一個(gè)屬性是cancelsTouchesInView譬淳,默認(rèn)為YES档址,設(shè)置為NO就可以使touchesbegan響應(yīng)了。

參考:一個(gè)Bug引發(fā)的對(duì)UIGestureRecognizer的思考

參考##

iOS 事件攔截

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末邻梆,一起剝皮案震驚了整個(gè)濱河市守伸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浦妄,老刑警劉巖尼摹,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異剂娄,居然都是意外死亡蠢涝,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門阅懦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)和二,“玉大人,你說(shuō)我怎么就攤上這事耳胎」呗溃” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵怕午,是天一觀的道長(zhǎng)废登。 經(jīng)常有香客問(wèn)我,道長(zhǎng)郁惜,這世上最難降的妖魔是什么钳宪? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮扳炬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搔体。我一直安慰自己恨樟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布疚俱。 她就那樣靜靜地躺著劝术,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上养晋,一...
    開(kāi)封第一講書(shū)人閱讀 51,165評(píng)論 1 299
  • 那天衬吆,我揣著相機(jī)與錄音,去河邊找鬼绳泉。 笑死逊抡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的零酪。 我是一名探鬼主播冒嫡,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼四苇!你這毒婦竟也來(lái)了孝凌?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤月腋,失蹤者是張志新(化名)和其女友劉穎蟀架,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體榆骚,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡片拍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寨躁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片穆碎。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖职恳,靈堂內(nèi)的尸體忽然破棺而出所禀,到底是詐尸還是另有隱情,我是刑警寧澤放钦,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布色徘,位于F島的核電站,受9級(jí)特大地震影響操禀,放射性物質(zhì)發(fā)生泄漏褂策。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一颓屑、第九天 我趴在偏房一處隱蔽的房頂上張望斤寂。 院中可真熱鬧,春花似錦揪惦、人聲如沸遍搞。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)溪猿。三九已至钩杰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诊县,已是汗流浹背讲弄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留依痊,地道東北人避除。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像抗悍,于是被迫代替她去往敵國(guó)和親驹饺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容