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

时间:2012-07-19 16:50:29

标签: objective-c ios uiwebview subview

新的一天,一个新的问题!

我一直在开发一款应用程序,要求我在用户手指触摸屏幕时显示一个圆圈。

我跟踪了在子类化UIWindow上找到的tutorialmy comment解释了如果使用Storyboard和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.webView替换为self.view),它工作正常,绘制我点击并拖动的圆圈,然后当我释放按钮时淡出

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

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

任何人都可以帮我弄清楚为什么不出现这种情况?是否还有其他需要注意的代码,或者为什么我不能这样做?

非常感谢!

修改

到目前为止,我已上传了我的资源here (MediaFire)

编辑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");
}

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

有没有人知道UIWebView中的任何特殊功能,以便在触摸事件上有重复的实例?

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

userInteractionEnabled的默认值UIImageViewNO。您可能需要将其设置为YES

答案 2 :(得分:0)

问题解决了:

不幸的是,这是由一些完全不同的原因引起的,所以谢谢大家的帮助。

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

我的最新评论为here