在UIPanGestureRecognizer和重新启用的UIScrollView之间连续滚动 [英] Continuous scrolling between UIPanGestureRecognizer and re-enabled UIScrollView

查看:696
本文介绍了在UIPanGestureRecognizer和重新启用的UIScrollView之间连续滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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



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



我试过切换 panGestureRecognizer.cancelsTouchesInView = NO; 但它似乎没有任何效果(我正在重新启用滚动时立即删除此识别器但是我是否这样做并不能解决我的问题)。我还查看了延迟... UIGestureRecognizer 的属性,但它们似乎没有帮助,或者。



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

解决方案

如果您只是定位,答案会更容易一些iOS 5及更高版本,因为在这种情况下你真的应该重用UIScrollView panGestureRecognizer属性。



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

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

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


  1. 子类UIScrollView(或UIScrollView的另一个子类,取决于您的需要)。

  2. 覆盖所有初始值设定项以确保您的设置代码被叫。

  3. 声明BOOL属性并覆盖setContentOffset:如上所述。

  4. 在你的设置代码中,设置一个UIPanGestureRecognizer和设置状态变量以允许编程滚动(假设这是您想要的默认状态):

      panRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture :)] autorelease]; 
    //这些属性可能会根据您的需要而改变
    panRecognizer.cancelsTouchesInView = NO;
    panRecognizer.delaysTouchesBegan = NO;
    panRecognizer.delaysTouchesEnded = NO;
    [self addGestureRecognizer:panRecognizer];
    panRecognizer.delegate = self;

    self.programaticScrollEnabled = YES;


  5. 管理可以同时进行的手势。在我的情况下:

       - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
    {
    返回YES;
    }


  6. 在任何需要的地方重新打开程序化滚动。例如:

       - (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer 
    {
    self.programaticScrollEnabled =是;
    }

    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
    {
    self.programaticScrollEnabled = YES;
    返回YES;
    }



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?

解决方案

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;
    }
    

这篇关于在UIPanGestureRecognizer和重新启用的UIScrollView之间连续滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆