【问题标题】:Continuous scrolling between UIPanGestureRecognizer and re-enabled UIScrollView在 UIPanGestureRecognizer 和重新启用的 UIScrollView 之间连续滚动
【发布时间】:2012-01-03 20:17:38
【问题描述】:

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

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

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

我尝试切换panGestureRecognizer.cancelsTouchesInView = NO;,但它似乎没有任何效果(我目前正在删除此识别器,一旦我重新启用滚动但我是否这样做并不能解决我的问题)。我还查看了 UIGestureRecognizerdelays... 属性,但它们似乎也没有帮助。

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

【问题讨论】:

  • 您是否尝试在gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: 方法中返回YES
  • @Hejazi 是的,我也实现了那个委托方法(并设置了我的委托),但是当手指仍然向下时它不会被调用(只有当我抬起并再次放下手指时这个委托方法是否被调用)。

标签: objective-c ios uiscrollview uipangesturerecognizer


【解决方案1】:

如果您只针对 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];
    //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. 管理哪些手势可以同时发生。就我而言:

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        return YES;
    }
    
  6. 在您需要的任何地方重新启用程序化滚动。例如:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-05
    • 2020-04-07
    • 1970-01-01
    • 2018-01-31
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    相关资源
    最近更新 更多