日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[搬运] iOS 7 侧滑返回手势使用和错误集

發布時間:2025/5/22 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [搬运] iOS 7 侧滑返回手势使用和错误集 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

原文:http://blog.sina.com.cn/s/blog_65c178a80102v0f4.html


前言:
ios7開始 蘋果增加了頁面 右滑返回的效果;具體的是以UINavigationController為容器的ViewController間右滑切換頁面。
代碼里的設置是:

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

可以看到蘋果給navigationController添加了一個手勢(具體為UIScreenEdgePanGestureRecognizer(邊緣手勢,同樣是ios7以后才有的)),就是利用這個手勢實現的 ios7的側滑返回。

問題1:
然而事情并非我們想的那么簡單。
1.當我們用系統的UINavigationController,并且也是利用系統的navigateBar的時候,是完全沒有問題的
2.但是當我們沒有用系統的navigateBar或者自定義了返回按鈕的時候,這個時候 右滑返回是失效的。

解決(問題1)辦法:
對于這種失效的情況,考慮到interactivePopGestureRecognizer也有delegate屬性,替換默認的self.navigationController.interactivePopGestureRecognizer.delegate來配置右滑返回的表現也是可行的。

我們可以在NavigationController中設置一下:
self.navigationController.interactivePopGestureRecognizer.delegate?=(id)self

問題2
但是出現很多問題,比如說在rootViewController的時候這個手勢也可以響應,導致整個程序頁面不響應;push了多層后,快速的觸發兩次手勢,也會錯亂

解決(問題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
借鑒了別人的方法:具體是通過 獲取當前pushView棧里的當前顯示的VC,根據這個VC來決定 是否開啟手勢(如果currentShowVC 是當前顯示的,則開啟手勢;如果 currentShowVC為nil,則代表在主頁面,關閉手勢)
注:
當時試了一種方法 就是滑動的時候來回設置?interactivePopGestureRecognizer的delegate;發現 會有crash,原因就是 因為 我把 當前顯示的VC設置為了這個手勢的delegate,但當這個VC消失的時候,這個delegate便被釋放了,導致crash

至此,覺得ios7上的右滑返回大功告成了,心里正happy,媽蛋,發現了一個可恥的bug:
UIScrollView 上 右滑返回的手勢失靈了,靠!!!!!!

問題三:

UIScrollView上手勢失靈:
經研究,發現是UIScrollView上已經添加了 panGestureRecognizer(滑動)手勢



解決(問題三)辦法:
參考: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;

?一句話總結就是此方法返回YES時,手勢事件會一直往下傳遞,不論當前層次是否對該事件進行響應。

?@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來說,它們對事件的接收順序和對事件的響應是可以分開設置的,即存在接收鏈和響應鏈。接收鏈如上文所述,和UIView綁定,由UIView的層次決定接收順序。

而響應鏈在apple君的定義下,邏輯出奇的簡單,只有一個方法可以設置多個gestureRecognizer的響應關系:

//?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都是一個有限狀態機,上述方法會在兩個gestureRecognizer間建立一個依托于state的依賴關系,當被依賴的gestureRecognizer.state = failed時,另一個gestureRecognizer才能對手勢進行響應。

所以,只需要

[_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 的 釋放導致crash的問題
http://www.2cto.com/kf/201401/272886.html


轉載于:https://www.cnblogs.com/madordie/p/4357685.html

總結

以上是生活随笔為你收集整理的[搬运] iOS 7 侧滑返回手势使用和错误集的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。