如何检测UIImageView外部的点击事件

4

我有一个UIImageView作为子视图添加到了界面上,当用户点击一个按钮时它会显示出来。

当用户在应用的任何部分以外的地方轻触屏幕时,我希望UIImageView消失。

@interface SomeMasterViewController : UITableViewController <clip>

<clip>

@property (strong, nonatomic) UIImageView *someImageView;

在stackoverflow和苹果文档中有一些提示看起来像是我需要的:

然而,我想确认我的方法是否正确。我理解代码需要:

  1. 注册一个UITapGestureRecognizer以获取应用程序中可能发生的所有触摸事件

  2. UITapGestureRecognizer应设置cancelsTouchesInView,delaysTouchesBegan和delaysTouchesEnded为NO。

  3. 将这些触摸事件与someImageView(如何使用UIView hitTest:withEvent?)进行比较

更新:我正在为主UIWindow注册UITapGestureRecognizer。

最终未解决的部分

我有一个handleTap:(UITapGestureRecognizer *),由UITapGestureRecognizer调用。我如何接收给出的UITapGestureRecognizer,并检查点击是否在UIImageView之外?locationInView方法看起来很有前途,但结果并不是我所期望的。我希望在点击某个特定的UIImageView时能看到它,而在点击其他地方时则看不到它。我感觉locationInView方法使用不正确。

这是我的locationInView方法调用:

- (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer.state != UIGestureRecognizerStateEnded) {
        NSLog(@"handleTap NOT given UIGestureRecognizerStateEnded so nothing more to do");
        return;        
    }

    UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
    CGPoint point = [gestureRecognizer locationInView:mainWindow];
    NSLog(@"point x,y computed as the location in a given view is %f %f", point.x, point.y);

    UIView *touchedView = [mainWindow hitTest:point withEvent:nil];
    NSLog(@"touchedView = %@", touchedView); 
}

我得到以下输出:
<clip>point x,y computed as the location in a given view is 0.000000 0.000000

<clip>touchedView = <UIWindow: 0x8c4e530; frame = (0 0; 768 1024); opaque = NO; autoresize = RM+BM; layer = <UIWindowLayer: 0x8c4c940>>
2个回答

4
我认为您只需要使用[event touchesForView:<image view>],如果返回一个空数组,就可以关闭图像视图。在表格视图控制器的touchesBegan:withEvent:中执行此操作,并确保调用[super touchesBegan:touches withEvent:event],否则您的表格视图将完全停止工作。您可能甚至不需要实现touchesEnded:/Cancelled:...touchesMoved:...
在这种情况下,UITapGestureRecognizer 显然过于复杂。

谢谢!顺便问一下,你是不是指的是touchesBegan:withEvent而不是"touchesBegan:touches forEvent:event",对吧?或者我有什么理解错误吗? :) - finneycanhelp
我喜欢这个建议。然而,在UITableViewController中,touchesBegan:withEvent没有被调用。我认为我遇到了https://dev59.com/tljUa4cB1Zd3GeqPNg3Q的问题。 - finneycanhelp
是的,你说得对。两次。不确定如何修复这个问题,我会尝试一下并回复你。如果你解决了,请告诉我们! - samson
另外,你应该看一下关于UIImageView覆盖的这篇文章。我认为,如果你想让图片在表格视图之上,你应该考虑其中的方法,使用一个新的UIWindow。在这种情况下,你也可能需要子类化UIImageView来捕获触摸事件... - samson
另一个问题中提出了一个稍微不同且简单的想法:http://stackoverflow.com/questions/10067059/why-does-the-ipad-become-nonresponsive-after-uigesturerecognizer-is-added-to-uiw “创建一个UIWindow子类”。 - finneycanhelp

2
您可以使用触控功能来完成这个操作:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

当用户第一次触摸屏幕时,会调用您的touchBegan函数。

在touchBegan中:

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

    CGPoint pt = [[touches anyObject] locationInView:self]; 
}

所以你有用户触摸的点。然后你必须找到这个点是否在你的UIImageView中。

但是如果你能给你的UIImageView添加标签,那就会非常容易。

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

      UITouch *touch = [touches anyObject ];

      if( yourImageView.tag==[touch view].tag){

         [[self.view viewWithTag:yourImageView.tag] removeFromSuperView];
         [yourImageView release];

      }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接