重新发出触摸事件

发布于 2024-11-25 18:33:17 字数 2696 浏览 1 评论 0原文

我正在尝试创建一个覆盖视图,该视图监视触摸然后消失,但还将触摸事件转发到视图下方的任何内容。

我的测试应用程序有一个内部带有按钮的视图。我将覆盖视图添加为另一个子视图(本质上与按钮同级),它占据了整个屏幕。

对于我尝试的两种解决方案,覆盖层都会保持状态以确定它如何响应触摸。当接收到touchesBegan事件时,覆盖层将停止响应hitTest或pointInside,直到收到touchesCancelled或touchesEnded。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if(_respondToTouch)
    {
        NSLog(@"Responding to hit test");
        return [super hitTest:point withEvent:event];
    }
    NSLog(@"Ignoring hit test");
    return nil;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    if(_respondToTouch)
    {
        NSLog(@"Responding to point inside");
        return [super pointInside:point withEvent:event];
    }
    NSLog(@"Ignoring point inside");
    return NO;
}

对于我的第一种方法,我尝试重新发出事件:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if(!_respondToTouch)
    {
        NSLog(@"Ignoring touches began");
        return;
    }
    NSLog(@"Responding to touches began");
    _respondToTouch = NO;

    [[UIApplication sharedApplication] sendEvent:event];
}

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches cancelled");
    _respondToTouch = YES;
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches ended");
    _respondToTouch = YES;
}

但是,按钮没有响应重新发出的事件。

我的第二种方法是使用 hitTest 来发现覆盖层下方的视图(我的按钮),然后直接向其发送 TouchXXX 消息:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches began");
    _respondToTouch = NO;
    UITouch* touch = [touches anyObject];
    _touchDelegate = [[UIApplication sharedApplication].keyWindow hitTest:[touch locationInView:self.superview] withEvent:event];
    CGPoint locationInView = [touch locationInView:_touchDelegate];
    NSLog(@"Sending touch %@ to view %@. location in view = %f, %f", touch, _touchDelegate, locationInView.x, locationInView.y);
    [_touchDelegate touchesBegan:touches withEvent:event];
}

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches cancelled");
    [_touchDelegate touchesCancelled:touches withEvent:event];
    _respondToTouch = YES;
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches ended");
    [_touchDelegate touchesEnded:touches withEvent:event];
    _respondToTouch = YES;
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches moved");
    [_touchDelegate touchesMoved:touches withEvent:event];
}

它找到按钮(根据日志),但按钮在以下情况下根本没有反应:我对它调用touchesXXX。

我不确定还可以尝试什么,因为按钮不会响应直接调用 TouchBegan =/

I'm trying to create an overlay view that monitors for touches and then disappears, but also forwards touch events to whatever is underneath the view.

My test app has a view with a button inside. I add the overlay view as another subview (sibling to the button, essentially), which takes up the entire screen.

For both solutions I tried, the overlay keeps state to determine how it responds to a touch. When a touchesBegan event is received, the overlay will stop responding to hitTest or pointInside until it receives a touchesCancelled or touchesEnded.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if(_respondToTouch)
    {
        NSLog(@"Responding to hit test");
        return [super hitTest:point withEvent:event];
    }
    NSLog(@"Ignoring hit test");
    return nil;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    if(_respondToTouch)
    {
        NSLog(@"Responding to point inside");
        return [super pointInside:point withEvent:event];
    }
    NSLog(@"Ignoring point inside");
    return NO;
}

For my first approach, I tried re-issuing the event:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if(!_respondToTouch)
    {
        NSLog(@"Ignoring touches began");
        return;
    }
    NSLog(@"Responding to touches began");
    _respondToTouch = NO;

    [[UIApplication sharedApplication] sendEvent:event];
}

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches cancelled");
    _respondToTouch = YES;
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches ended");
    _respondToTouch = YES;
}

However, the button didn't respond to the re-issued event.

My second approach was to use hitTest to discover the view (my button) underneath the overlay, and then send a touchesXXX message directly to it:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches began");
    _respondToTouch = NO;
    UITouch* touch = [touches anyObject];
    _touchDelegate = [[UIApplication sharedApplication].keyWindow hitTest:[touch locationInView:self.superview] withEvent:event];
    CGPoint locationInView = [touch locationInView:_touchDelegate];
    NSLog(@"Sending touch %@ to view %@. location in view = %f, %f", touch, _touchDelegate, locationInView.x, locationInView.y);
    [_touchDelegate touchesBegan:touches withEvent:event];
}

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches cancelled");
    [_touchDelegate touchesCancelled:touches withEvent:event];
    _respondToTouch = YES;
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches ended");
    [_touchDelegate touchesEnded:touches withEvent:event];
    _respondToTouch = YES;
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches moved");
    [_touchDelegate touchesMoved:touches withEvent:event];
}

It finds the button (according to the logs), but the button doesn't react at all when I invoke touchesXXX on it.

I'm not sure what else to try since the button won't respond to a direct invocation of touchesBegan =/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文