更改FirstResponder

时间:2011-05-27 14:01:54

标签: iphone uiresponder

Hola家伙。 我在触摸处理和UIResponder方面遇到了一些问题。

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

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

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

似乎我的UIImageView吞下了我的触摸,因此我的新按钮无法感受到手指的移动。 我试图辞职第一响应者,但似乎没有效果。

我的自定义按钮工作得非常好,但只有在我释放第一个水龙头然后再次点击新的显示器按钮时才会工作。

有什么建议吗? 提前谢谢。

这里有一些代码:

在我的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方法手动处理circularMenu中的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];
            }
        }
    }
}

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

有什么想法吗?

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

3 个答案:

答案 0 :(得分: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];
    }
}

这会检查手势的最后一次触摸是否在按钮内,并向内部事件发送内部触摸。

答案 1 :(得分: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];
}

答案 2 :(得分:0)

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

myImageView.userInteractionEnabled = NO;

这样,UIImageView将不再听取这些接触。

让我知道它是否有效。