Continuous scrolling between UIPanGestureRecognizer and re-enabled UIScrollView

一个人想着一个人 提交于 2019-12-22 03:24:33

问题


I've got a UIScrollView with paging enabled, and I've added my own UIPanGestureRegonizer to it. Under certain instances, my view controller will set scrollview.scrollEnabled = NO, and then add the pan gesture recognizer to it (I'm not using the scrollview's own recognizer).

So, scrolling is disabled but I'm waiting for user touches from my gesture recognizer. When it recognizes, it calls its action in which I re-enable scrolling.

The problem is, while the user still has a finger down, my scrollview doesn't track with the finger. It doesn't start scrolling until the finger is lifted and then dragged again. So my gesture recognizer is swallowing all the touches and not forwarding any to the scrollview.

I've tried toggling panGestureRecognizer.cancelsTouchesInView = NO; but it doesn't seem to have any effect (I'm currently removing this recognizer as soon as I re-enable scrolling but whether I do this or not doesn't solve my problem). I've also looked into the delays... properties of UIGestureRecognizer but they don't seem to be helping, either.

Any ideas? How can I get these events to continue to forward to my scrollview?


回答1:


The answer is a bit easier if you are only targeting iOS 5 and up, because in that case you really ought to reuse the UIScrollView panGestureRecognizer property.

In any case, the key step is to NOT reuse scrollEnabled, but instead to subclass UIScrollView, create your own property to manage this state, and override setContentOffset:.

    - (void) setContentOffset:(CGPoint)contentOffset
    {
        if(self.programaticScrollEnabled)
            [super setContentOffset:contentOffset];
    }

Here's one possible iOS 4+ Solution:

  1. Subclass UIScrollView (or subclass another subclass of UIScrollView, depending on your needs).
  2. Override all the initializers to ensure your setup code is called.
  3. Declare the BOOL property and override setContentOffset: as described above.
  4. In your setup code, set up a UIPanGestureRecognizer and set your state variable to allow programatic scrolling (assuming that's the default state you want):

    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;
    
  5. Manage which gestures can occur simultaneously. In my case:

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        return YES;
    }
    
  6. Turn programatic scrolling back on wherever you need it. For example:

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


来源:https://stackoverflow.com/questions/8718073/continuous-scrolling-between-uipangesturerecognizer-and-re-enabled-uiscrollview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!