可拖动的UIView在添加到UIScrollView后停止发布touchesBegan

时间:2014-03-16 17:33:10

标签: ios iphone objective-c uiscrollview touchesbegan

在Xcode 5.1中,我为iPhone创建了a simple test app

app screenshot

结构是:scrollView -> contentView -> imageView -> image 1000 x 1000位于顶部。

在单一视图应用的底部,我有七个可拖动的自定义UIView

拖动是使用touchesXXXX方法在Tile.m中实施的。

我的问题是:一旦我向ViewController.m文件中的contentView添加了一个可拖动的磁贴 - 我再也无法拖动它了:

- (void) handleTileMoved:(NSNotification*)notification {
    Tile* tile = (Tile*)notification.object;
    //return;

    if (tile.superview != _scrollView && CGRectIntersectsRect(tile.frame, _scrollView.frame)) {
        [tile removeFromSuperview];
        [_contentView addSubview:tile];
        [_contentView bringSubviewToFront:tile];
    }
}

不再为touchesBegan调用Tile,就像scrollView会掩盖该事件一样。

I've searched around并建议使用以下方法(在我的自定义GameBoard.m中)扩展UIScrollView类:

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView* result = [super hitTest:point withEvent:event];

    NSLog(@"%s: %hhd", __PRETTY_FUNCTION__,
          [result.superview isKindOfClass:[Tile class]]);

    self.scrollEnabled = ![result.superview isKindOfClass:[Tile class]];
    return result;
}

不幸的是,这无效并在调试器中打印0

3 个答案:

答案 0 :(得分:6)

问题在于,部分原因是因为内容视图上禁用了用户交互。但是,启用用户交互会在视图捕获所有触摸时禁用滚动。所以这是解决方案。在storyboard中启用用户交互,但是像这样继承内容视图:

@interface LNContentView : UIView

@end

@implementation LNContentView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView* result = [super hitTest:point withEvent:event];

    return result == self ? nil : result;
}

@end

这样,只有当接受视图不是内容视图self时,才会通过命中测试。

这是我的提交: https://github.com/LeoNatan/ios-newbie

答案 1 :(得分:1)

Tile视图没有触及的原因是滚动视图的平移手势识别器会消耗这些事件。您需要的是,在每个磁贴上附加UIPanGestureRecongnizer并按如下方式配置它们:

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; // handle drag in pan:method
[tile addGestureRecognizer:pan];
UIPanGestureRecognizer *scrollPan = self.scrollView.panGestureRecognizer;
[scrollPan requireGestureRecognizerToFail:pan];

在这里,您可以让滚动视图的平移手势识别器知道您只希望在没有拖动任何图块的情况下进行滚动。

我已经检查过这种方法 - 确实有效。关于您的代码,您需要处理手势识别器中的所有触摸而不是平铺视图,因为触摸事件可能会在经过测试的视图的手势识别器到达视图本身之前被消耗/延迟。请参阅UIGestureRecognizer documentation以了解有关该主题的更多信息。

答案 2 :(得分:0)

看起来层次结构中的一个视图是捕获事件。

看一下

部分
  

响应者链遵循特定的传递路径

Apple doc的here

编辑:

抱歉,我是从记忆中写的。这就是我在自己的应用程序中解决类似问题的方法:

我在想要检测触摸的视图中使用UITapGestureRecognizer。实现UITapGestureRecognizer的以下委托方法:

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event

触动' set包含接收事件的所有对象(视图)。