移动到外部视图并重新进入后,UITapGestureRecognizer将被忽略

时间:2012-06-07 18:09:38

标签: iphone objective-c ios gesture uitapgesturerecognizer

我的UILabel中有一个UIView小孩。我将它用作状态面板,如果不显示任何内容,它将滑出视图。我这样做只需将其动画为origin.y减去标签的高度。

只要显示消息,我就会将标签滑回视图中。几秒钟后,它会滑出。这很好。

我还在标签上添加了UITapGestureRecognizer,因此用户可以立即关闭该消息,而无需等待它自动消失。

我的问题是,一旦标签移到视图之外,手势识别器就不会触发。当标签完全在视图内部并且可见时,我初始化并添加手势识别器。它第一次按预期工作。但是当消息重新出现时,手势识别器似乎被删除或禁用。

每次我的动画完整块中的标签完全出现在屏幕上时,我也尝试添加gr,但这也无济于事。

有人可以向我解释一下这里发生了什么,以及如何让识别器一直工作?

如果您需要和进一步的信息,请告诉我。

更新

我做了一些进一步的测试,当我在showError调用中记录lblError.gestureRecognizers时,我得到了这个:

<UITapGestureRecognizer: 0x6b153f0; state = Possible; view = <UILabel 0x6b14fa0>; target= <(action=dismissError:, target=<OptionViewController 0x686d2a0>)>>

在我创作之后,它就完全一样了。所以它仍然存在,我猜触摸事件没有达到它。

更新2

我更进了一步。

问题似乎是我将标签移动到y坐标0.这可能是GestureRecognizer代码中的一个错误,因为当我将它设置为0.1时它会起作用!

看起来系统“认为”标签不在视图中,因此禁用了触摸处理等。 ^^

这解决了问题的一半,但在另一侧创建了一个新问题。现在手势识别器工作,延迟移出动画不再被触发。

所以我认为真正的问题是移出动画是在移入后立即触发的。即使它被延迟,它也会阻止标签接收任何类型的触摸事件。

代码

//添加手势识别器(在viewDidLoad中)

UITapGestureRecognizer *errorDismissGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissError:)];
[lblError addGestureRecognizer:errorDismissGesture];

// display error
- (void)showError:(NSString *)message {
  [lblError setText:message];
  [UIView animateWithDuration:0.5 
                   animations:^(void) { 
                     CGRect frame = lblError.frame;
                     frame.size.width = self.view.bounds.size.width;
                     frame.origin.y = 0;
                     lblError.frame = frame;
                   } 
                   completion:^(BOOL finished) {
                     [UIView animateWithDuration:0.5
                                           delay:2.0
                                         options:UIViewAnimationOptionCurveEaseOut
                                      animations:^(void) {
                                        CGRect frame = lblError.frame;
                                        frame.origin.y = -40.0f;
                                        lblError.frame = frame;
                                      }
                                      completion:^(BOOL finished) {}];
                   }];
}

- (void)dismissError:(UIGestureRecognizer *)sender {
  [UIView animateWithDuration:0.3
                   animations:^(void) {
                     CGRect frame = lblError.frame;
                     frame.origin.y = -40.0;
                     lblError.frame = frame;
                   }
                   completion:^(BOOL finished) {}];
}

谢谢和问候, 托马斯

1 个答案:

答案 0 :(得分:1)

我终于解决了!

似乎延迟移出动画会以某种方式阻止标签接收任何触摸事件。即使是UIAnimationOptionAllowUserInteraction也无济于事。

所以我用一个定时调用替换了延迟动画,这使得代码甚至有点可读。这就是它现在的样子。

 - (void)showError:(NSString *)message {
     [lblError setText:message];
     [UIView animateWithDuration:0.5 
                     animations:^(void) { 
                         CGRect frame = lblError.frame;
                         frame.size.width = self.view.bounds.size.width;
                         frame.origin.y = 0.1;
                         lblError.frame = frame;
                     } 
                     completion:^(BOOL finished) {
                         if (finished) {
                            [_moveOutTimer invalidate];
                             _moveOutTimer = nil;
                             _moveOutTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(dismissError:) userInfo:nil repeats:NO];
                         }
                     }];
}

- (void)dismissError:(UIGestureRecognizer *)sender {
    [_moveOutTimer invalidate];

    [UIView animateWithDuration:0.3
                    animations:^(void) {
                         CGRect frame = lblError.frame;
                         frame.origin.y = -40.0;
                         lblError.frame = frame;
                     }
                     completion:^(BOOL finished) {}];
}