在UIPanGestureRecognizer和重新启用的UIScrollView之间连续滚动

jbr*_*nan 11 objective-c uiscrollview ios uipangesturerecognizer

我UIScrollView启用了分页功能,并且我已添加了自己的分页功能UIPanGestureRegonizer.在某些情况下,我的视图控制器将设置scrollview.scrollEnabled = NO,然后添加平移手势识别器(我没有使用scrollview自己的识别器).

因此,滚动被禁用但我正在等待来自我的手势识别器的用户触摸.当它识别时,它会调用其重新启用滚动的操作.

问题是,当用户仍然用手指按下时,我的滚动视图不会用手指跟踪.在手指抬起然后再次拖动之前,它不会开始滚动.因此,我的手势识别器正在吞咽所有触摸而不是转发任何滚动视图.

我试过切换panGestureRecognizer.cancelsTouchesInView = NO;但它似乎没有任何影响(我正在重新启用滚动时我正在删除此识别器但是我是否这样做并不能解决我的问题).我也研究了它们的delays...属性,UIGestureRecognizer但它们似乎也没有帮助.

有任何想法吗?如何让这些事件继续转发到我的滚动视图?

Pro*_*eus 5

如果您只针对iOS 5及更高版本,答案会更容易一些,因为在这种情况下,您确实应该重用UIScrollView panGestureRecognizer属性.

在任何情况下,关键步骤是不重用scrollEnabled,而是重用子类UIScrollView,创建自己的属性来管理这个状态,并覆盖setContentOffset:.

    - (void) setContentOffset:(CGPoint)contentOffset
    {
        if(self.programaticScrollEnabled)
            [super setContentOffset:contentOffset];
    }
Run Code Online (Sandbox Code Playgroud)

这是一个可能的iOS 4+解决方案:

  1. 子类UIScrollView(或子类UIScrollView的另一个子类,具体取决于您的需要).
  2. 覆盖所有初始值设定项以确保调用您的设置代码.
  3. 声明BOOL属性并覆盖setContentOffset:如上所述.
  4. 在您的设置代码中,设置UIPanGestureRecognizer并设置状态变量以允许编程滚动(假设这是您想要的默认状态):

    panRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)] autorelease];
    //These properties may change according to your needs
    panRecognizer.cancelsTouchesInView = NO;
    panRecognizer.delaysTouchesBegan = NO;
    panRecognizer.delaysTouchesEnded = NO;
    [self addGestureRecognizer:panRecognizer];
    panRecognizer.delegate = self;
    
    self.programaticScrollEnabled = YES;
    
    Run Code Online (Sandbox Code Playgroud)
  5. 管理可以同时进行的手势.就我而言:

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        return YES;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  6. 在任何需要的地方打开程序化滚动.例如:

    - (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
    {
        self.programaticScrollEnabled = YES;
    }
    
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
    {
        self.programaticScrollEnabled = YES;
        return YES;
    }
    
    Run Code Online (Sandbox Code Playgroud)