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

防止在iOS7中滚动UIScrollView的子视图上发生触摸事件,ios,uiscrollview,ios7,uicontrol,Ios,Uiscrollview,Ios7,Uicontrol,我在UIScrollView中有一个UIControl。在我的UIControl的init中,我装配了一些触摸事件处理程序,例如 [self addTarget:_delegate action:@selector(touchedDown) forControlEvents:UIControlEventTouchDown]; 当我执行以下操作时,iOS6和iOS7的行为不同: 滑动UIScrollView以开始滚动 点击UIScrollView以停止滚动 在iOS6中,我的应

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

[self addTarget:_delegate
         action:@selector(touchedDown) forControlEvents:UIControlEventTouchDown];
当我执行以下操作时,iOS6和iOS7的行为不同:

  • 滑动UIScrollView以开始滚动
  • 点击UIScrollView以停止滚动
  • 在iOS6中,我的应用程序继续按预期运行:第2步的轻触不会调用
    touchedDown
    ——UIScrollView会在立即停止滚动时吞下触摸事件

    但在iOS7中,UIScrollView会按预期停止滚动,而
    touchedDown
    仍被调用


    是否有记录在案的API变更?我希望我的应用程序与iOS7中的iOS6表现相同。

    不是很优雅,但在没有更好的想法的情况下,以下是对我有效的方法:

    • 在UIScroll视图中,将
      canCancelContentTouches
      设置为
      YES
      ,将
      delaysContentTouches
      设置为
      NO
    • 在UIScrollViewDelegate中,当UIScrollView滚动时,切换UIScrollView的子视图的
      userInteractionEnabled
      属性:
    • 将UIScrollView子类化并实现:
    • 子类化UIControl并实现
      touchscancelled:withEvent
      以反转
      UIControlEventTouchDown
      处理程序所做的任何操作:

    在UIScrollView上的UIButtons也一样。这是我目前的解决方案

    不使用uicontrol事件触地事件的内容:

    [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 touchesCanceled方法将被删除


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

    只需替换事件类型即可

    UIControlEventTouchDown
    必须是iOS 7的
    UIControlEventTouchUpInside

    解决方法

    @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
    

    在UIScrollView上的UIButtons也一样。在iOS6中,您可以通过抓取按钮来滑动UIScrollView,按钮上不会调用UIControlEventTouchDown。在iOS7中,将调用uicontroleventground。实际上,这太棒了!我一直在寻找困难的解决方案,比如实施hitTest,但这正是我需要的。(虽然这并不是对最初问题的回答)很好,这正是我想要的:)对iPhone很好,而不是iPad
    [button addTarget:_delegate
             action:@selector(touchedDown) forControlEvents:UIControlEventTouchDown];
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    // my scroll content touch logic
    }
    
    @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