解決右滑返回手勢和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右滑返回手勢深度全解和最佳實施方案iOS
- Flutter和iOS手勢衝突解決思路FlutteriOS
- 聊聊Flutter中的常見滑動手勢衝突Flutter
- iOS開發之解決MMDrawerController側滑選單與中心檢視手勢衝突iOSController
- iOS 開發中遇到的手勢衝突iOS
- 一種巢狀滑動衝突的解決方案巢狀
- Android View 滑動衝突解決方式以及原理AndroidView
- 一種非巢狀滑動衝突的解決方案巢狀
- git 解決衝突Git
- Git 解決衝突Git
- 程式衝突及其解決
- git pull 衝突解決Git
- hash衝突解決方法
- Git衝突解決技巧Git
- git pull衝突的解決方案Git
- JAR衝突問題的解決JAR
- RecyclerView 、ViewPager 左右滑動衝突Viewpager
- Swift 專案總結 05 系統邊緣右滑 pop 手勢調整Swift
- 解決Flutter的ListView巢狀ListView滑動衝突以及無限高度問題FlutterView巢狀
- SVN解決衝突 記錄
- css命名衝突解決方法CSS
- 依賴衝突時的解決方法
- Git 衝突了怎麼辦,如何高效快速的解決程式碼衝突?Git
- cad快捷鍵和win10衝突怎麼辦_cad快捷鍵和win10衝突的解決方法Win10
- git 解決版本衝突問題Git
- 解決預設方法衝突的規則
- hash解決衝突的方法優缺點
- 解決動態庫的符號衝突符號
- flutter dialog中軟鍵盤遮擋解決衝突Flutter
- git如何進行程式碼的合併和衝突的解決Git行程
- kotlin語言:解決drawerLayout與viewpager的衝突、NavigationView側滑裡面menu的點選事件KotlinViewpagerNavigation事件
- 手勢檢測跟蹤解決方案
- scrollview 的滑動衝突 viewpager等都適用Viewpager
- View 體系詳解:座標系、滑動、手勢和事件分發機制View事件
- QianKun 解決element ui 和 element-plus 樣式衝突UI
- 【Flutter 專題】130 圖解 DraggableScrollableSheet 可手勢滑動的選單欄Flutter圖解
- Android 解決BottomSheetDialog 拖曳衝突問題Android
- Android com.android.support衝突解決Android
- Git 解決本地遠端版本衝突Git