0

大家好。我在触摸处理和 UIResponder 方面遇到了一点问题。

我的目标是管理一次触摸(移动)以与不同的视图进行交互。

我向我的 UIImageView 添加了一个手势识别器,它向我的 customViewController 发送一条简单的消息。它在点击的 UIImageView 上分配并显示自定义视图(继承 UIButton)。

我将能够(无需释放初始手指点击)将触摸移动发送到我新分配的自定义按钮。

似乎我的 UIImageView 吞下了我的触摸,所以我的新 Button 感觉不到手指的移动。我试图辞去第一响应者的职务,但似乎没有效果。

我的自定义按钮工作得很好,但前提是我释放第一次点击,然后再次点击新的显示按钮。

有什么建议吗?先感谢您。

这里有一些代码:

在我的 viewController 中,我将一个 longPressGestureRecognizer 附加到我的 profileImageView 中,它在 profileImageView 周围绘制了一个圆形按钮。

-(void)showMenu:(UIGestureRecognizer*)gesture {
    [profileImageView removeGestureRecognizer:gesture];
    [profileImageView setUserInteractionEnabled:NO];

    ConcentricRadius radius;
    radius.externalRadius = 75;
    radius.internalRadius = 45;

    GTCircularButton *circularMenu = [[[GTCircularButton alloc] initWithImage:[UIImage imageNamed:@"radio.png"] highlightedImage:[UIImage imageNamed:@"radio_selected.png"] radius:radius] autorelease];
    [circularMenu setTag:kCircularTagControllerCircularMenu];
    [circularMenu setCenter:[profileImageView center]];

    // Buttons' frames will be set up by the circularMenu
    UIButton *button1 = [[[UIButton alloc] init] autorelease];
    UIButton *button2 = [[[UIButton alloc] init] autorelease];
    UIButton *button3 = [[[UIButton alloc] init] autorelease];
    UIButton *button4 = [[[UIButton alloc] init] autorelease];

    [circularMenu setButtons:[NSArray arrayWithObjects:button1, button2, button3, button4, nil]];

    //[[self view] addSubview:circularMenu];
    [[self view] insertSubview:circularMenu belowSubview:profileImageView];
}

现在我使用 touchMoved 方法手动处理 circleMenu 内的 touchEvent。

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint touchLocation = [(UITouch*)[touches anyObject] locationInView:self];

    for (UIView *aSubview in _roundButtons) {
        if ([aSubview isKindOfClass:[UIButton class]]) {
            UIButton *aButton = (UIButton*)aSubview;
            CGPoint buttonTouchPointConverted =  [aButton convertPoint:touchLocation toView:aButton];

            if (CGRectContainsPoint([[aButton layer] frame], buttonTouchPointConverted)) {
                [self rotateHighlightImage:aButton];
            }
        }
    }
}

目标始终是处理手势识别器的结束并将触摸事件传递给创建的新实例,而无需将手指从屏幕上抬起。

有任何想法吗?

PD:如果我使用 addTarget:action:forControlEvents: 在我的按钮(1、2、3 和 4)上,我使用 touchMoved 手动处理触摸,检测到 touchEvent 的按钮会吞下它并使其他按钮无法感觉到触摸移动他们。

4

3 回答 3

1

touchesEnded:withEvent:将必须与您的相同,touchesMoved:withEvent:只是它必须调用可能与控制事件Touch Up Inside事件相关的方法。

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint touchLocation = [(UITouch*)[touches anyObject] locationInView:self];

    for (UIView *aSubview in _roundButtons) {
        if ([aSubview isKindOfClass:[UIButton class]]) {
            UIButton *aButton = (UIButton*)aSubview;
            CGPoint buttonTouchPointConverted =  [aButton convertPoint:touchLocation toView:aButton];

            if (CGRectContainsPoint([[aButton layer] frame], buttonTouchPointConverted)) {
                [aButton sendActionsForControlEvents:UIControlEventTouchUpInside];
                return;
            }
        }
    }
}

我所做的唯一更改是让按钮为我们发送控制事件。

原始答案

在处理您的手势的函数中,执行此操作,

if ( gesture.state == UIGestureRecognizerStateEnded ) {
    CGPoint point = [gesture locationInView:button];
    if ( CGRectContainsPoint(button.bounds, point) ) {
        [button sendActionsForControlEvents:UIControlEventTouchUpInside];
    }
}

这会检查手势的最后一次触摸是否在按钮内部,并向其所有目标发送 touch up inside 事件。

于 2011-05-27T18:08:32.227 回答
1

好的,伙计们终于解决了我的问题,我达到了我的目标!

我发现了真正的问题。只需 GestureRecognizer 处理触摸事件,直到它的状态设置为 UIGestureRecognizerStateEnded ,因此 GestureRecognizer 吞下触摸事件,没有机会将触摸事件发送到响应者链的其余部分。

我再次阅读了 UIGestureRecognizer 类参考,发现该属性已启用。

为了解决我的问题,当手势启动目标方法时我做的第一件事是将启用的手势设置为 NO。这样,手势释放立即触摸控制和touchMoved可以被执行。

希望这对某人有所帮助。

以上修改代码:

-(void)showMenu:(UIGestureRecognizer*)gesture {
    [gesture setEnabled:NO];          // This is the key line of my problem!!
    [profileImageView removeGestureRecognizer:gesture];
    [profileImageView setUserInteractionEnabled:NO];

    ConcentricRadius radius;
    radius.externalRadius = 75;
    radius.internalRadius = 45;

    GTCircularButton *circularMenu = [[[GTCircularButton alloc] initWithImage:[UIImage imageNamed:@"radio.png"] highlightedImage:[UIImage imageNamed:@"radio_selected.png"] radius:radius] autorelease];
    [circularMenu setTag:kCircularTagControllerCircularMenu];
    [circularMenu setCenter:[profileImageView center]];

    // Buttons' frames will be set up by the circularMenu
    UIButton *button1 = [[[UIButton alloc] init] autorelease];
    UIButton *button2 = [[[UIButton alloc] init] autorelease];
    UIButton *button3 = [[[UIButton alloc] init] autorelease];
    UIButton *button4 = [[[UIButton alloc] init] autorelease];

    [circularMenu setButtons:[NSArray arrayWithObjects:button1, button2, button3, button4, nil]];

    //[[self view] addSubview:circularMenu];
    [[self view] insertSubview:circularMenu belowSubview:profileImageView];
}
于 2011-05-30T12:59:27.037 回答
0

我认为您应该在创建按钮后更改视图的设置。例如。

myImageView.userInteractionEnabled = NO;

这样,UIImageView就不会再听触摸了。

让我知道它是否有效。

于 2011-05-27T15:49:09.753 回答