UIWebView addSubview:UIImageView在触摸事件触发时不显示

问题描述:

新的一天,一个新的问题!UIWebView addSubview:UIImageView在触摸事件触发时不显示

我一直在研究一个应用程序,它需要我在用户手指触摸屏幕时显示一个圆圈。

我跟着tutorial我发现子类UIWindow和my comment解释如何传递这些触摸,如果你正在使用故事板和ARC。

我使用下面的代码(其是基于this tutorial),以使触摸指示符来显示:

#pragma mark - Touch Events 
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { 
    NSArray *subviews = [self.webView subviews]; 
    for (UIView *view in subviews) 
    { 
     // Check if view is scrollview 
     if ([view isKindOfClass:[UserTouchImageView class]]) 
     { 
      [view removeFromSuperview]; 
     } 
    } 

    // Enumerate over all the touches and draw a red dot on the screen where the touches were 
    [touches enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { 
     // Get a single touch and it's location 
     UITouch *touch = obj; 
     CGPoint touchPoint = [touch locationInView:self.webView]; 

     // Add touch indicator 
     UserTouchImageView *touchView = [[UserTouchImageView alloc] initWithFrame:CGRectMake(touchPoint.x -15, touchPoint.y -15, 30, 30)]; 
     [self.webView addSubview:touchView]; 
    }]; 
    NSLog(@"Touches began"); 
} 
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { 
    NSArray *subviews = [self.webView subviews]; 
    for (UIView *view in subviews) 
    { 
     // Check if view is scrollview 
     if ([view isKindOfClass:[UserTouchImageView class]]) 
     { 
      [view removeFromSuperview]; 
     } 
    } 

    // Enumerate over all the touches and draw a red dot on the screen where the touches were 
    [touches enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { 
     // Get a single touch and it's location 
     UITouch *touch = obj; 
     CGPoint touchPoint = [touch locationInView:self.webView]; 

     // Draw a red circle where the touch occurred 
     UserTouchImageView *touchView = [[UserTouchImageView alloc] initWithFrame:CGRectMake(touchPoint.x -15, touchPoint.y -15, 30, 30)]; 
     [self.webView addSubview:touchView]; 
    }]; 
    NSLog(@"Touches moved"); 
} 
- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { 
    NSArray *subviews = [self.webView subviews]; 
    for (UIView *view in subviews) 
    { 
     // Check if view is scrollview 
     if ([view isKindOfClass:[UserTouchImageView class]]) 
     { 
      [UIView animateWithDuration:0.5f 
          animations:^{ 
           view.alpha = 0.0; 
          } 
          completion:^(BOOL finished) { 
           [view removeFromSuperview]; 
          }]; 
     } 
    } 
    NSLog(@"Touches ended"); 
} 
- (void) touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { 
    NSArray *subviews = [self.webView subviews]; 
    for (UIView *view in subviews) 
    { 
     // Check if view is scrollview 
     if ([view isKindOfClass:[UserTouchImageView class]]) 
     { 
      [view removeFromSuperview]; 
     } 
    } 
    NSLog(@"Touches cancelled"); 
} 

UserTouchImageView是的UIImageView的子类,与变更到默认感:

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code 
     self.image = [UIImage imageNamed:@"greyCircle.png"]; 
     self.alpha = 0.5f; 
    } 
    return self; 
} 

我已经测试了这个没有UIWebview的代码(用self.view代替self.webView),它工作正常,绘制了我点击和拖动的圆,然后当我释放按钮时淡出。

我还成功实例化了UserTouchImageView,并将其添加到viewViewer的viewDidLoad方法的webView中。

只要我把UIWebview放在上面的代码中,同一行([self.webView addSubview:touchView];)就不起作用。我仍然可以将NSLog消息发送到控制台,但子视图不会被明显添加。

任何人都可以帮我找出为什么这不会出现?是否还有其他我需要注意的代码,或者我无法做到这一点的任何原因?

非常感谢!

编辑

我已经上传我的源至今here (MediaFire)

EDIT 2

我下面添加了两个方法:

-(void)listWebViewSubViews 
{ 
    NSLog(@"BEGIN LISTING SUBVIEWS"); 
    for (UIView *view in [self.webView subviews]) { 
     NSLog(@"Subview: %@", view.description); 
    } 
    NSLog(@"END LISTING SUBVIEWS"); 
} 
-(void)view:(UIView *)view addTouchIndicatorWithCentreAtPoint:(CGPoint)point 
{ 
    NSLog(@"View: %@, x: %f, y: %f", view.description, point.x, point.y); 

    // Add touch indicator 
    UserTouchImageView *touchView = [[UserTouchImageView alloc] initWithFrame:CGRectMake(point.x -15, point.y -15, 30, 30)]; 

    [view addSubview:touchView]; 


} 

这些被称为从UIWebView外部的两个按钮,以及内部的的touchesBegan方法:

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { 
    NSArray *subviews = [self.webView subviews]; 
    for (UIView *view in subviews) 
    { 
     if ([view isKindOfClass:[UserTouchImageView class]]) 
     { 
      [view removeFromSuperview]; 
     } 
    } 

    [touches enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { 
     UITouch *touch = obj; 
     CGPoint touchPoint = [touch locationInView:self.webView]; 

     [self view:self.webView addTouchIndicatorWithCentreAtPoint:touchPoint]; 

     [self listWebViewSubViews]; 
    }]; 
    NSLog(@"Touches began"); 
} 

的记录似乎表明,web视图通过self.webView引用WITHIN的触摸开始从两个按钮引用时方法比一个完全独立的实例。我可以通过按钮添加多个子视图,然后列出它们,并且它们都显示在日志中,但是当我单击以在模拟器上触摸时,这些额外的子视图都不会列出。

有谁知道任何特殊功能的UIWebView有触摸事件的重复实例吗?

+0

首先,检查你要添加的子视图不'nil'。然后尝试添加一个'setNeedsDisplay'调用。这也可能是因为你在一个街区内打电话。你在块内尝试了'NSLog'吗? – Dustin 2012-07-19 16:55:18

+0

嗨达斯汀,谢谢你的回复。它完全通过了我,因为它在块内部被调用,所以我已经尝试了你的两个建议,对象不是'nil','setNeedsDisplay'没有可见的效果。我也尝试在调用dispatch_async(dispatch_get_main_queue(),^ {});''时调用'[selv.webView addSubview:touchView];'。那也行不通。我会继续寻找,谢谢你的帮助! – 2012-07-20 09:36:29

问题解决了:

很不幸,这是由somethign完全不同造成的,所以谢谢大家对你给予的帮助。

这个问题来自于我尝试修复代码以与故事板一起运行。我试图从故事板访问视图控制器,并将其作为接收触摸事件的视图作为优先事项添加(请参阅我链接到的教程,以及我也回复了的评论)。我应该一直在使用self.window.rootViewController。

我更新的评论是here

A UIWebView不是一个视图,而是一个视图的集合。当您将子视图添加到UIWebView时,新的子视图将添加到子视图的层次结构中。您的新子视图可能被添加在其他不透明视图后面。它在那里,但隐藏。我建议将此指标视图添加到层​​次结构中的不同视图。

+0

感谢您提供这些信息,我从一个按钮中调用了相同的代码,这个按钮显示在'UIWebView'上。我遇到的问题是,当从触摸事件调用同一个方法时,看起来通过触摸事件访问的webView完全独立于按钮的方式,也就是NSLog中所有webview子视图的方法当从触摸事件中调用时,不会列出按钮添加的子视图。我也尝试在webview上添加一个空白的UIView作为子视图,但是这会从web视图中去除互动。 – 2012-07-20 13:42:52

+0

@ mr-berna:我尝试添加'[view bringSubviewToFront:touchView];'来添加子视图的方法,但它没有任何区别。 – 2012-07-20 13:56:10

userInteractionEnabled对于UIImageView的默认值是NO。您可能需要将其设置为YES

+0

嗨,本笃,这没有帮助,不幸的是。我遇到的唯一问题是UIWebView在直接从touchbegan等方法添加时不显示子视图。它可以工作,如果我使用外部输入,如按钮,但。 – 2012-07-20 13:39:36