0

我正在尝试将 UITapGestureRecognizer 添加到 UILabel 中,如果用户有新公告,它将从状态栏向下动画。我希望用户能够单击标签并直接转到公告。UITapGetureRecognizer 不工作。这是我正在做的事情:

+(void)animateDown:(NSString *)title view:(UIViewController *)view color:(UIColor *)color time:(NSTimeInterval)duration
{
    view = view.navigationController.visibleViewController;
    if (currentlyDisplayed == NO) {
        if (color == nil) color = customGreen;
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0 ,-40, 320, 40)];
        label.text = title;
        label.font = [UIFont fontWithName:@"STHeitiTC-Medium" size:18];
        label.backgroundColor = color;//customBlue;//[UIColor colorWithRed:0.0993145 green:0.0957361 blue:0.562879 alpha:.8f];
        label.layer.cornerRadius = 15.0f;
        [label setTextAlignment:NSTextAlignmentCenter];
        [label setMinimumFontSize:12];
        [label setAdjustsFontSizeToFitWidth:YES];
        [label sizeToFit];
        label.textColor = [UIColor whiteColor];
        if ([color isEqual:customBlue]) {
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
            tap.numberOfTapsRequired = 1;
            tap.numberOfTouchesRequired = 1;
            label.userInteractionEnabled = YES;
            [label addGestureRecognizer:tap];
        }
        [view.view addSubview:label];
        [view.view bringSubviewToFront:label];
        currentlyDisplayed = YES;
        [UIView animateWithDuration:.5f delay:0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionCurveEaseIn animations:^{
            label.frame = CGRectMake(0, 0, 320, 40);
        }completion:^(BOOL finished) {
            CGFloat dur;
            if (duration == 0)  {
                dur = .5f;
            }else {
                dur = duration;
            }

            [UIView animateWithDuration:1 delay:dur options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionCurveEaseOut animations:^{
                label.frame = CGRectMake(0,-40,320,40);
            }completion:^(BOOL finished) {
                if (finished) [label removeFromSuperview];
                currentlyDisplayed = NO;
            }];
        }]; 
    }else {
        NSMethodSignature *sig = [[self class] methodSignatureForSelector:@selector(animateDown:view:color:time:)];
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
        [invocation setSelector:@selector(animateDown:view:color:time:)];
        [invocation setTarget:self];
        [invocation setArgument:&title atIndex:2];
        [invocation setArgument:&view atIndex:3];
        [invocation setArgument:&color atIndex:4];
        [invocation setArgument:&duration atIndex:5];
        [NSTimer scheduledTimerWithTimeInterval:0.5 invocation:invocation repeats:NO];
    }
}



- (IBAction)onTap:(UIPanGestureRecognizer *)recognizer {
    [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"announcementTapped" object:nil]];
    NSLog(@"tapped");
}

onTap 方法永远不会被调用......它进入 if 语句......参见图片: 在此处输入图像描述

4

3 回答 3

9

它无法识别触摸,因为它在UIView动画块中被点击。

尝试UIViewAnimationOptionAllowUserInteraction在动画时添加选项参数。


编辑

问题是UIView' 层的实际位置在最终目的地。你想要做的是检查它presentationLayer是否在被点击的位置。

为了解决这个问题,您可以将手势添加到主视图而不是实际标签,然后点击检查触摸位置是否在标签的presentationLayer:

- (IBAction)onTap:(UITapGestureRecognizer *)tapGestureRecognizer {
    CGPoint point = [tapGestureRecognizer locationInView:tapGestureRecognizer.view];
    BOOL labelTapped = [self.label.layer.presentationLayer hitTest:point] != nil;
    if (labelTapped) {
        // do something
    }
}
于 2012-12-14T18:05:16.377 回答
1

您需要检查Userinteraction的属性UILabel是真还是假,如果它是假的,然后将其设置为真。您还可以检查您的故事板或 xib 文件内部并相应地检查它。

于 2018-02-12T15:57:01.567 回答
0
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];  
//...//
- (IBAction)onTap:(UIPanGestureRecognizer *)recognizer {

更改您的onTap签名以匹配您的 GestureRecognizer 类UITap...

于 2012-12-14T17:58:48.140 回答