UIButton 永远不会在 UIImageView 的框架区域内响应

Posted

技术标签:

【中文标题】UIButton 永远不会在 UIImageView 的框架区域内响应【英文标题】:UIButton never responds within a UIImageView's frame area 【发布时间】:2012-07-25 14:26:44 【问题描述】:

这是我的视图层次结构: parentView (UIView) 有一个 UIImageView 作为它的子视图,而它又有一个 UIButton 作为它的子视图。

left = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"left.png"]];
left.userInteractionEnabled = YES;
[parentView addSubview:left];

back = [UIButton buttonWithType:UIButtonTypeCustom];
[back setImage:[UIImage imageNamed:@"Arrow-left.png"] forState:UIControlStateNormal];
[back addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside];
back.showsTouchWhenHighlighted = YES;
[left addSubview:back];

一切正常显示,但按钮不响应触摸。如果我将其框架从 UIImageView 的框架移到其他地方并将其设置为父视图(UIView)的子视图,它会做出响应。但事情就是这样。

即使我设置为 parentView 的 subView,如果按钮位于 UIImageView 的框架区域内,它也不会响应。图像视图的 userInteractionEnabled 属性已设置为 YES。知道发生了什么吗?

【问题讨论】:

back: 的代码是什么。您是否在其中放置了NSLog 以查看它是否确实在触发? 您能否尝试将按钮添加到parentView 而不是left @EricBrotto 它已经在我的问题中了。我试过这样做,只要按钮不落在 imageview 的框架区域中,它就可以工作。 @WrightsCS 这个问题非常多地表明它在放置在图像视图的框架区域之外时触发。 愚蠢的问题,但是imageView下面的按钮是什么?你能把它放在上面吗? 【参考方案1】:

UIImageView 关闭 userInteraction - 打开它,按钮就会起作用。

编辑:

所以我几乎完全按照所写的方式使用了您的代码 - 一个红鲱鱼是您说这一切看起来都很好。对我来说,自定义按钮的框架为 0,0,0,0,所以我什么也没看到。当我设置框架时,一切都很完美:

    UIButton *back = [UIButton buttonWithType:UIButtonTypeCustom];
    UIImage *image = [UIImage imageNamed:@"46-truck.png"];
    assert(image);

    [back setImage:image forState:UIControlStateNormal];
    [back addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
    back.showsTouchWhenHighlighted = YES;
    back.frame = (CGRect) 0,0, image.size;

NSLog(@"FRAME: %@", NSStringFromCGRect(back.frame) );
    [imageView addSubview:back];

因此,如果您需要在运行时探测超级视图以找出是什么,您可以使用下面的代码。 [UIView dumpSuperviews:back msg:@"Darn Bark Button"];

@interface UIView (Utilities_Private)

+ (void)appendView:(UIView *)v toStr:(NSMutableString *)str;

@end

@implementation UIView (Utilities_Private)

+ (void)appendView:(UIView *)a toStr:(NSMutableString *)str

    [str appendFormat:@"  %@: frame=%@ bounds=%@ layerFrame=%@ tag=%d userInteraction=%d alpha=%f hidden=%d\n", 
        NSStringFromClass([a class]),
        NSStringFromCGRect(a.frame),
        NSStringFromCGRect(a.bounds),
        NSStringFromCGRect(a.layer.frame),
        a.tag, 
        a.userInteractionEnabled,
        a.alpha,
        a.isHidden
        ];


@end

@implementation UIView (Utilities)

+ (void)dumpSuperviews:(UIView *)v msg:(NSString *)msg

    NSMutableString *str = [NSMutableString stringWithCapacity:256];

    while(v) 
        [self appendView:v toStr:str];
        v = v.superview;
    
    [str appendString:@"\n"];

    NSLog(@"%@:\n%@", msg, str);


+ (void)dumpSubviews:(UIView *)v msg:(NSString *)msg

    NSMutableString *str = [NSMutableString stringWithCapacity:256];

    if(v) [self appendView:v toStr:str];
    for(UIView *a in v.subviews) 
        [self appendView:a toStr:str];
    
    [str appendString:@"\n"];

    NSLog(@"%@:\n%@", msg, str);


@end

【讨论】:

如果您阅读了代码和问题的最后一部分,他已经启用了它。 left.userInteractionEnabled = YES; 啊,是的,我草草下结论并没有看到那行 :-(。它太常见了。无论如何,父视图是否有 userInteractionEnabled?我从未向 imageView 添加按钮,但是我添加了一个手势识别器。 我已经用另一种方法正确设置了框架,该方法用于为屏幕中的所有视图设置框架。所以它也会出现在正确的框架中。 好吧,我的意思是 - 我创建了一个 UIImageView,将其添加到视图中,然后在代码中完全按照您所做的那样创建按钮,将其添加到 ImageView,并且效果很好。因此,这比您所暴露的要多。另一个视图覆盖 imageView 阻塞事件等。转储视图层次结构 - 我将在我的答案中添加代码。【参考方案2】:

也许

parentView.userInteractionEnabled = YES;

或父视图框架太小,无法按住按钮或图像视图。检查父视图的大小;

【讨论】:

parentView 是一个UIView,所以默认情况下会设置它,而且看起来按钮在不与UIImageView重叠时有效。【参考方案3】:

我以前也遇到过这种情况。我认为这是一个吞噬事件的超级视图。

我知道您已经说过将其添加到 parentView 仅在它不与图像视图重叠时才有效。如果禁用图像视图上的用户交互,按钮事件在添加到 parentView 时是否一致触发?

【讨论】:

是的。它适用于删除 imageView。只有在层次结构中为 UIView->UIImageView->UIButton 时它才不起作用。不管 UIButton 是 UIImageView 还是 UIView 的子视图。 要明确一点,当你说它“只有在什么时候不起作用”它是 UIImageView 的子视图(UIView->UIImageView->UIButton)时,你也意味着它在什么时候不起作用它是 UIView 的子视图(UIView->UIImageView & UIView->UIButton)?编辑:这只是您的最后一条评论!=您在 OP 中所说的内容。 是的。在这两种情况下都不起作用。在第二种情况下,它仅在按钮的框架设置在 Imageview 之外时才起作用 在我看来,UIImageViewUIButton 得到它之前就吃掉了触摸事件。不过,我不记得如何解决这个问题,抱歉,正如你所说,你的订单是正确的,所以我不知道为什么如果按钮在它上面,imageview 会吃掉这个事件。您可以尝试将UIButton 显式移到前面; [parentView bringSubviewToFront:back]. 我必须补充一点,我的应用程序中的另一部分具有类似的场景,但它只是一个带有 UIButton 子视图的 UIImageView。在 userInteractionEnabled 设置为 YES 的情况下可以正常工作。当 UIView 在 UIImageView 后面时,它会停止。【参考方案4】:

您实际上需要设置userInteractionEnabled = NO 以允许触摸通过。

取自here。

【讨论】:

啊.. 不起作用。我正在以适当的层次结构添加视图。我什至尝试设置 zPositions 以正确使用视图层。即使那样也行不通。【参考方案5】:
left.userInteractionEnabled = YES;

把这一行放在最后。

【讨论】:

以上是关于UIButton 永远不会在 UIImageView 的框架区域内响应的主要内容,如果未能解决你的问题,请参考以下文章

未调用 UIButton 选择器

针对不同状态更改 UIButton 的渐变

设置 UIButton alpha 在 iOS 7 上无法正常工作。

Xcode 6.3.2 - iOS - 模棱两可的 UIImageView

在 tableView 单元格中显示和隐藏 UIImageView

UIButton 多个事件