通过触摸到下面的UIViews

Mag*_*ave 64 iphone uiview uiimageview ios uitapgesturerecognizer

我有一个UIView4个按钮,另一个UIView在按钮视图的顶部.最顶层的视图包含UIImageView一个UITapGestureRecognizeron.

我试图创建的行为是,当用户点击UIImageView它时,它在屏幕右下角的小视图和动画变大之间切换.当它很大时,我想要禁用底部视图上的按钮,当它很小时,在右下角我希望触摸传递到按钮并让它们正常工作.我几乎在那里,但除非我禁用UserInteractions顶视图,否则无法通过按钮进行操作.

initWithFrame:在顶视图中有这个:

// Add a gesture recognizer to the image view
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTapped:)];
tapGestureRecognizer.cancelsTouchesInView = NO;
[imageView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];
Run Code Online (Sandbox Code Playgroud)

我这是我的imageTapped:方法:

- (void) imageTapped:(UITapGestureRecognizer *) gestureRecognizer {
    // Toggle between expanding and contracting the image
    if (expanded) {
        [self contractAnimated:YES];
        expanded = NO;
        gestureRecognizer.cancelsTouchesInView = NO;
        self.userInteractionEnabled = NO;
        self.exclusiveTouch = NO;
    }
    else {
        [self expandAnimated:YES];
        expanded = YES;
        gestureRecognizer.cancelsTouchesInView = NO;
        self.userInteractionEnabled = YES;
        self.exclusiveTouch = YES;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,当图像很大时,按钮处于非活动状态,当我触摸图像时,它会缩小并且按钮变为活动状态.但是,小图像不会接收到触摸,因此不会扩展.

如果我self.userInteractionEnabled = YES在两种情况下都设置了,那么图像在触摸时会扩展和收缩,但按钮从不接收触摸并且就像禁用一样.

触摸时是否有图像扩展和收缩,但如果图像处于收缩状态,下面的按钮只能接收触摸?我在这里做了些蠢事并且遗漏了一些明显的东西吗?

我绝对会疯狂地试图让这个工作,所以任何帮助将不胜感激,

戴夫

更新:

为了进一步测试,我覆盖了touchesBegan:touchesCancelled:方法,并在包含UIImageView的视图中调用了它们的超级实现.使用上面的代码,touchesCancelled:永远不会调用它,并且touchesBegan:始终调用它.

因此看起来视图正在接触,它们只是没有传递到下面的视图.

UPDATE

这是因为响应链的工作方式吗?我的视图层次结构如下所示:

VC - View1
     -View2
      -imageView1 (has tapGestureRecogniser)
      -imageView2
     -View3
      -button1
      -button2
Run Code Online (Sandbox Code Playgroud)

我认为操作系统首先执行hitTest,因为View2位于前面,所以应该获得所有触摸,除非将ViewInteractions设置为NO,否则这些内容永远不会传递给View3,在这种情况下,imageView1也会被阻止接收触摸.它是如何工作的,View2是否有办法通过它接触到View3?

Mag*_*ave 91

我认为UIGestureRecognizer是一个红鲱鱼.最后解决这个我超越了我的pointInside:withEvent:方法UIView:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    BOOL pointInside = NO;

    if (CGRectContainsPoint(imageView.frame, point) || expanded) pointInside = YES;

    return pointInside;
}
Run Code Online (Sandbox Code Playgroud)

如果您触摸imageView或者设置了扩展标志,这会导致视图捕获所有触摸.如果它没有展开,那么只有当它们在imageView上时才捕获触摸.

通过返回NO,顶级VC的View查询其视图层次结构的其余部分以查找命中.

  • 感谢您在这个答案中的信息!但是,我最终覆盖了`hitTest`而不是'pointInside`.这是因为我试图确保*parent*视图没有窃取任何点击,但希望所有子视图都能够.通过重写`hitTest`,您可以简单地调用基本实现来确定哪个视图被轻击,如果该视图恰好是`self`,则返回`nil`. (23认同)

Mic*_*ael 60

选择你的Viewin StoryboardXIB和......


在此输入图像描述


或者在斯威夫特

view.isUserInteractionEnabled = false
Run Code Online (Sandbox Code Playgroud)

  • 这也将禁用视图子视图上的触摸..如果有的话 (63认同)

joh*_*ohn 6

查看UIGestureRecognizerDelegate协议.特别,gestureRecognizer:shouldReceiveTouch:

你会想要把你的每UIGestureRecognizer一个属性UIViewController,

// .h
@property (nonatomic, strong) UITapGestureRecognizer *lowerTap;

// .m
@synthesize lowerTap;

// When you are adding the gesture recognizer to the image view
self.lowerTap = tapGestureRecognizer
Run Code Online (Sandbox Code Playgroud)

确保你成为UIViewController一名代表,

[self.lowerTap setDelegate: self];
Run Code Online (Sandbox Code Playgroud)

然后,你会有这样的事情,

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if (expanded && gestureRecognizer == self.lowerTap) {    
        return NO;
    }
    else {
        return YES;
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这不是确切的代码.但这是你想要遵循的一般模式.

  • 我非常好,看了一下代表协议,我看不出这对我有用.我希望手势识别器始终接收触摸,我有时希望能够将它们传递给窗口中的其他视图而不是取消它们.根据docs cancelsTouchesInView = NO应该传递它们,只要父视图将userInteractionEnabled设置为NO也可以执行. (2认同)