解決右滑返回手勢和UIScrollView中的手勢衝突
首先說一下我們專案是怎麼簡單解決的
@interface BaseNav : UINavigationController
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationBar.hidden = YES;
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.viewControllers.count >= 1)
{
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
self.interactivePopGestureRecognizer.delegate = self;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
BOOL ok = YES; // 預設為支援右滑反回
if ([self.topViewController isKindOfClass:[XTYBaseWebViewController class] ]|| [self.topViewController isKindOfClass:[GenericWebViewController class] ]||[self.topViewController isKindOfClass:[TempActViewController class] ]) {
ok = NO;
}
return ok;
}
當讓這可能不是最好的解決方案 於是又是在網上各種查
出現的原因
iOS系統中,滑動返回手勢,其實是一個UIPanGestureRecognizer,系統預設的操作是隻有滑動螢幕的左邊的某個位置,UIPanGestureRecognizer才會起作用。UIScrollView的滑動手勢也是UIPanGestureRecognizer。UIGestureRecognizer和UIView是多對一的關係(具體點這裡),UIGestureRecognizer一定要和view進行繫結才能發揮作用。因此不難想象,UIGestureRecognizer對於螢幕上的手勢事件,其接收順序和UIView的層次結構是一致的
UINavigationController.view —> UIViewController.view —> UIScrollView —> Screen and User's finger
即UIScrollView的panGestureRecognizer先接收到了手勢事件,直接就地處理而沒有往下傳遞。
實際上這就是兩個panGestureRecognizer共存的問題。
解決方案一
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([self panBack:gestureRecognizer]) {
return NO;
}
return YES;
}
- (BOOL)panBack:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer == self.panGestureRecognizer) {
UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
CGPoint point = [pan translationInView:self];
UIGestureRecognizerState state = gestureRecognizer.state;
if (UIGestureRecognizerStateBegan == state || UIGestureRecognizerStatePossible == state) {
CGPoint location = [gestureRecognizer locationInView:self];
if (point.x > 0 && location.x < 20 && self.contentOffset.x <= 0) {
return YES;
}
}
}
return NO;
}
解決方案二
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
// 首先判斷otherGestureRecognizer是不是系統pop手勢
if ([otherGestureRecognizer.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")]) {
// 再判斷系統手勢的state是began還是fail,同時判斷scrollView的位置是不是正好在最左邊
if (otherGestureRecognizer.state == UIGestureRecognizerStateBegan && self.contentOffset.x == 0) {
return YES;
}
}
return NO;
}
原理:
scrollView的pan手勢會讓系統的pan手勢失效,所以我們只需要在系統手勢失效且scrollView的位置在初始位置的時候讓兩個手勢同時啟用就可以了。
下面一個 git 連線 運動 runtime 來做的側滑返回
https://github.com/W-King/PPX_LateralSpreads
相關文章
- iOS 側滑返回手勢與Scrollview衝突的解決辦法iOSView
- Flutter和iOS手勢衝突解決思路FlutteriOS
- iOS右滑返回手勢深度全解和最佳實施方案iOS
- 聊聊Flutter中的常見滑動手勢衝突Flutter
- 巢狀UIScrollview的滑動衝突解決方案巢狀UIView
- android父子控制元件手勢衝突的解決Android控制元件
- iOS 開發中遇到的手勢衝突iOS
- UIPanGestureRecognizer進行檢視滑動並處理手勢衝突UI
- iOS開發之解決MMDrawerController側滑選單與中心檢視手勢衝突iOSController
- ScrollView 與ListView 滑動衝突解決View
- 一種巢狀滑動衝突的解決方案巢狀
- 一種非巢狀滑動衝突的解決方案巢狀
- Android View 滑動衝突解決方式以及原理AndroidView
- 實現全屏返回手勢
- 解決jquery和其他庫的衝突jQuery
- Eclipse中Egit衝突解決EclipseGit
- Android事件分發機制、滑動衝突解決Android事件
- PPT中聲音“衝突”的解決方法
- Git 解決衝突Git
- git 解決衝突Git
- 【筆記】Git 中的分支建立和衝突解決(命令列)筆記Git命令列
- 移動端右劃事件與瀏覽器右劃回退衝突解決方案事件瀏覽器
- SVN衝突解決和注意事項
- Maven中解決依賴衝突的問題Maven
- RecyclerView與下拉重新整理控制元件滑動衝突的解決View控制元件
- 解決ScrollView巢狀ViewPager出現的滑動衝突問題巢狀Viewpager
- 【Objective-C】解決輕拍手勢事件與TableView的Cell點選事件衝突的問題Object事件View
- 程式衝突及其解決
- git pull 衝突解決Git
- windows解決埠衝突Windows
- IP衝突解決方案
- SVN 版本衝突解決
- Swift 專案總結 05 系統邊緣右滑 pop 手勢調整Swift
- RecyclerView 、ViewPager 左右滑動衝突Viewpager
- git pull衝突的解決方案Git
- JAR衝突問題的解決JAR
- 關於hash衝突的解決
- 完美解決ScrollView巢狀ListView滑動衝突(有圖有真相)View巢狀