带有其他手势的 ScrollView 中的 2 个手指平移 - iOS SDK

Posted

技术标签:

【中文标题】带有其他手势的 ScrollView 中的 2 个手指平移 - iOS SDK【英文标题】:2 Finger Pan in ScrollView w/ Other Gestures - iOS SDK 【发布时间】:2013-01-17 06:13:16 【问题描述】:

我有一个主 UIView,其中包含一个滚动视图。我已经使用以下代码为 4 种类型的滑动为主视图设置了 UIGestureRecognizer:

UISwipeGestureRecognizer *swipeUpRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(upCommand)];
[swipeUpRecognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
[mainGameView addGestureRecognizer:swipeUpRecognizer];
... // Done 4 times for each direction

当我在滚动视图上禁用滚动时,这段代码效果很好(我可以在屏幕上的任意位置滑动,并且相关操作按预期执行)。但是,我想添加功能,以便如果我在滚动视图上触摸两根手指,我可以像滚动视图通常那样来回平移。我尝试在滚动视图中添加一个手势识别器来检测两个手指何时平移:

- (void)viewDidLoad

    UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(recognizePan)];
    panGestureRecognizer.minimumNumberOfTouches = 2;
    panGestureRecognizer.maximumNumberOfTouches = 2;
    [scrollView addGestureRecognizer:panGestureRecognizer];


- (void)recognizePan

    [gameScrollView setScrollEnabled:YES];

我将它与以下方法结合使用,以在手指抬起后再次禁用滚动:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

    [gameScrollView setScrollEnabled:NO];

这种方式有效,但不是我想要的方式。当我在滚动视图上拖动两个手指时,滚动将设置为启用,但我不能使用这两个手指滚动。我首先需要抬起两根手指,然后我可以用一根手指滚动(两根手指不起作用)。当我抬起可以滚动滚动视图的单根手指时,滚动被禁用,如 scrollViewDidEndDragging 中设置的那样。

显然,这种类型的滚动不会对用户非常友好,但我似乎找不到设置滚动视图的方法,因此它仅在两根手指在滚动视图上拖动时滚动。感谢您提前提供任何帮助。

~ 17 岁的业余 ios 开发人员和手势新手

编辑:根据this question 的建议之一,我尝试实现 UISubView 的子类来覆盖默认的 touchesBegan 方法,但我无法让它工作。

CustomScrollView.h:

@interface CustomScrollView : UIScrollView 



@end

CustomScrollView.m:

#import "CustomScrollView.h"

@implementation CustomScrollView

- (id)initWithFrame:(CGRect)frame 

  return [super initWithFrame:frame];


- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event 
   
  // What goes here so that The action it can be called from the ViewController.h


@end

ViewController.h:

#import <UIKit/UIKit.h>

@class CustomScrollView;

@interface ViewController : UIViewController <UIScrollViewDelegate>

  CustomScrollView *scrollView;


@end

ViewController.m:

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event 

  // What goes here?

【问题讨论】:

我已经回答了你的问题,试试吧,它对我有用 =) 如果对您没有帮助,请接受答案或添加评论 【参考方案1】:

继承ScrollView并实现如下方法:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 
  if(gestureRecognizer.numberOfTouches != 2) 
    return NO;
   else 
    return YES;
  

【讨论】:

【参考方案2】:

尝试继承 UIScrollView 并覆盖方法 touchesShouldBegin:withEvent:inContentView:。文档说明如下:

被子类覆盖以自定义手指在显示内容中触摸时的默认行为。

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view

因此,您可以检查您是否有不止一次触摸,并且只有返回一个真值。

【讨论】:

【参考方案3】:

我认为解决这个问题的起点是遵循 UIView 方法:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer

调用此方法时,我们可以检查触摸位置、触摸次数等,然后决定使用哪个识别器。如果你创建一个 UIScrollView 子类并覆盖 gestureRecognizerShouldBegin,你也可以控制 UIScrollView 的默认手势识别器(平移/缩放)。

当然,不需要使用 scrollEnabled 属性。

【讨论】:

【参考方案4】:

试试这个

  - (void)viewDidLoad
  

    [super viewDidLoad];


    UISwipeGestureRecognizer *swipeUpRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(upCommand)];
    swipeUpRecognizer.delegate = self;
    [swipeUpRecognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
    [self.view addGestureRecognizer:swipeUpRecognizer];
    scrollView.delegate = scrollView;

    panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(recognizePan:)];
    panGestureRecognizer.minimumNumberOfTouches = 1;
    panGestureRecognizer.maximumNumberOfTouches = 1;
    [self.scrollView addGestureRecognizer:panGestureRecognizer];


-(void)upCommand

    NSLog(@"up");    

-(void)viewDidAppear:(BOOL)animated

    scrollView.contentSize = CGSizeMake(320, 600);

- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


- (void)recognizePan:(UIGestureRecognizer*)recognizer

    NSLog(@"pan");//Does nothing but catches the pan of scrollview so it doesnt scroll



//simultan recognition of pan and gesture
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
    return YES;

panreconicer 捕捉到 Scrollview 中的单指滑动,因此视图不会滚动,然后添加

应该用手势识别器同时识别

使平移和手势都被捕捉到。

就是这样

编辑 你必须添加

<UIGestureRecognizerDelegate>

到您的 .h 文件

【讨论】:

以上是关于带有其他手势的 ScrollView 中的 2 个手指平移 - iOS SDK的主要内容,如果未能解决你的问题,请参考以下文章

iOS解决嵌套在ScrollView中的TableView滑动手势冲突问题

ScrollView 问题中的 Xamarin.Forms 捏手势

当ViewPager嵌套在ScrollView/ListView里时,手势冲突如何处理?

iOS LeftMenu抽屉效果与ScrollView共存时的手势冲突

scrollview添加手势 不影响子控件点击事件

ui scrollview 中没有手势识别器 uiimageview