ios 側(cè)滑返回

ios7開始 蘋果增加了頁面 右滑返回的效果;具體的是以UINavigationController為容器的ViewController間右滑切換頁面。代碼里的設(shè)置是:self.navigationController.interactivePopGestureRecognizer.enabled = YES;(default is YES)

可以看到蘋果給navigationController添加了一個手勢(具體為UIScreenEdgePanGestureRecognizer(邊緣手勢,同樣是ios7以后才有的)),就是利用這個手勢實現(xiàn)的 ios7的側(cè)滑返回。問題1:然而事情并非我們想的那么簡單。

1.當(dāng)我們用系統(tǒng)的UINavigationController,并且也是利用系統(tǒng)的navigateBar的時候,是完全沒有問題的2.但是當(dāng)我們沒有用系統(tǒng)的navigateBar或者自定義了返回按鈕的時候,這個時候 右滑返回是失效的。解決(問題1)辦法:對于這種失效的情況,考慮到interactivePopGestureRecognizer也有delegate屬性,替換默認(rèn)的self.navigationController.interactivePopGestureRecognizer.delegate來配置右滑返回的表現(xiàn)也是可行的。我們可以在主NavigationController中設(shè)置一下:self.navigationController.interactivePopGestureRecognizer.delegate =(id)self問題2:但是出現(xiàn)很多問題,比如說在rootViewController的時候這個手勢也可以響應(yīng),導(dǎo)致整個程序頁面不響應(yīng);push了多層后,快速的觸發(fā)兩次手勢,也會錯亂解決(問題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 mvc;

}?

-(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;elseself.currentShowVC = viewController;

}?

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{

if (gestureRecognizer == self.interactivePopGestureRecognizer) {return (self.currentShowVC == self.topViewController); //the most important}return YES;

}?

@end

借鑒了別人的方法:具體是通過 獲取當(dāng)前pushView棧里的當(dāng)前顯示的VC,根據(jù)這個VC來決定 是否開啟手勢(如果currentShowVC 是當(dāng)前顯示的,則開啟手勢;如果 currentShowVC為nil,則代表在主頁面,關(guān)閉手勢)注:當(dāng)時試了一種方法 就是滑動的時候來回設(shè)置 interactivePopGestureRecognizer的delegate;發(fā)現(xiàn) 會有crash,原因就是 因為 我把 當(dāng)前顯示的VC設(shè)置為了這個手勢的delegate,但當(dāng)這個VC消失的時候,這個delegate便被釋放了,導(dǎo)致crash至此,覺得ios7上的右滑返回大功告成了,心里正happy,媽蛋,發(fā)現(xiàn)了一個可恥的bug:UIScrollView 上 右滑返回的手勢失靈了,靠!?。。。?!

問題三:UIScrollView上手勢失靈:經(jīng)研究,發(fā)現(xiàn)是UIScrollView上已經(jīng)添加了 panGestureRecognizer(滑動)手勢ios7側(cè)滑返回解決(問題三)辦法:參考:http://www.cnblogs.com/lexingyu/p/3702742.html【

解決方案】蘋果以UIGestureRecognizerDelegate的形式,支持多個UIGestureRecognizer共存。其中的一個方法是:1 // called when the recognition of one of gestureRecognizer or otherGestureRecognizer would be blocked by the other 2 // return YES to allow both to recognize simultaneously. the default implementation returns NO (by default no two gestures can be recognized simultaneously) 3 // 4 // note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES 5 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer; 一句話總結(jié)就是此方法返回YES時,手勢事件會一直往下傳遞,不論當(dāng)前層次是否對該事件進(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;? ?

?}

}

事實上,對UIGestureRecognizer來說,它們對事件的接收順序和對事件的響應(yīng)是可以分開設(shè)置的,即存在接收鏈和響應(yīng)鏈。接收鏈如上文所述,和UIView綁定,由UIView的層次決定接收順序。而響應(yīng)鏈在apple君的定義下,邏輯出奇的簡單,只有一個方法可以設(shè)置多個gestureRecognizer的響應(yīng)關(guān)系:// create a relationship with another gesture recognizer that will prevent this gesture's actions from being called until otherGestureRecognizer transitions to UIGestureRecognizerStateFailed // if otherGestureRecognizer transitions to UIGestureRecognizerStateRecognized or UIGestureRecognizerStateBegan then this recognizer will instead transition to UIGestureRecognizerStateFailed // example usage: a single tap may require a double tap to fail - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;每個UIGesturerecognizer都是一個有限狀態(tài)機(jī),上述方法會在兩個gestureRecognizer間建立一個依托于state的依賴關(guān)系,當(dāng)被依賴的gestureRecognizer.state = failed時,另一個gestureRecognizer才能對手勢進(jìn)行響應(yīng)。所以,只需要[_scrollView.panGestureRecognizer requireGestureRecognizerToFail: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;

}

參考:牛逼 解決了iOS7下滑動返回與ScrollView共存http://www.cnblogs.com/lexingyu/p/3702742.html更牛逼? 解決了interactivePopGestureRecognizer.delegate 的 釋放導(dǎo)致crash的問題http://www.2cto.com/kf/201401/272886.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言:ios7開始 蘋果增加了頁面 右滑返回的效果;具體的是以UINavigationController為容器的...
    iPhone閱讀 3,844評論 2 3
  • 前言(其實就是廢話,可以忽略 = =) 側(cè)滑返回手勢是從iOS7開始增加的一個返回操作,經(jīng)歷了兩年時間估計iPho...
    LonlyCat閱讀 32,943評論 20 102
  • 如果系統(tǒng)的側(cè)滑返回用不了了,可以嘗試以下方法: 1 __weak typeof (self) weakSelf ...
    LUJQ閱讀 279評論 0 0
  • 1. 使用官方API解決Navigation側(cè)滑導(dǎo)致的Navigationbar異常顯示和隱藏的問題 參考:htt...
    曉飛90閱讀 4,404評論 0 1
  • 祈愿通過學(xué)習(xí)和實踐金剛智慧,實現(xiàn)自我成長,妥善處理家庭關(guān)系,社會關(guān)系,成為智慧的榜樣,并且通過幫助更多的人讓世界變...
    瑩火蟲兒閱讀 164評論 1 0

友情鏈接更多精彩內(nèi)容