防止在iOS7中滚动UIScrollView的子视图上的触摸事件

时间:2013-09-25 17:35:44

标签: ios uiscrollview ios7 uicontrol

我在UIScrollView中有一个UIControl。在我的UIControl的init中,我安装了一些触摸事件处理程序,例如

[self addTarget:_delegate
         action:@selector(touchedDown) forControlEvents:UIControlEventTouchDown];

当我执行以下操作时,iOS6和iOS7的行为会有所不同:

  1. 滑动UIScrollView以开始滚动
  2. 点按UIScrollView停止滚动
  3. 在iOS6中,我的应用程序继续按预期运行:步骤#2中的点按未调用 touchedDown - UIScrollView会在触发事件立即停止滚动时吞下触摸事件。 / p>

    但是在iOS7中,UIScrollView按预期停止滚动,而touchedDown 仍称为

    是否有文档化的API更改?我希望我的应用程序在iOS7中的行为与iOS6相同。

4 个答案:

答案 0 :(得分:9)

适用于iOS 7的

解决方法

@interface UIScrollViewFixed : UIScrollView

@end

@implementation UIScrollViewFixed

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (self.isDragging || self.isDecelerating) {
        return self;
    }
    return [super hitTest:point withEvent:event];
}

@end

答案 1 :(得分:4)

只需替换事件类型

即可

UIControlEventTouchDown必须为UIControlEventTouchUpInside

答案 2 :(得分:2)

不是很优雅,但在没有任何更好的想法的情况下,这就是现在对我有用的东西:

  • 在UIScrollView上,将canCancelContentTouches设为YES,将delaysContentTouches设为NO
  • 在UIScrollViewDelegate中,在UIScrollView滚动时切换UIScrollView的子视图的userInteractionEnabled属性:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [_contentView setUserInteractionEnabled:NO];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate) {
        [_contentView setUserInteractionEnabled:YES];
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [_contentView setUserInteractionEnabled:YES];
}
  • UIScrollView的子类并实现:
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
    return YES;
}
  • 对UIControl进行子类化并实现touchesCancelled:withEvent以反转UIControlEventTouchDown处理程序所做的任何事情:
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    //custom logic
}

答案 3 :(得分:0)

与UIScrollView上的UIButtons相同。这是我现在的解决方案。

而不是使用内容UIControlEventTouchDown事件:

[button addTarget:_delegate
         action:@selector(touchedDown) forControlEvents:UIControlEventTouchDown];

我在我的内容UIViewController中实现了UIResponder touchesEnded方法:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
// my scroll content touch logic
}

如果用户触摸内容并开始拖动touchesEnded处理程序将不会被调用。 UIResponder touchsCanceled方法将会。

如果用户未拖动UIscrollview,则触发touchesEnded处理程序,该处理程序可用于触摸逻辑。