I am trying to add a UITapGestureRecognizer to a UILabel that will animate down from the status bar if the user has a new announcement. I want the user to be able to click the label and goto the announcement directly. The UITapGetureRecognizer isn’t working. Here is what I am doing:
+(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");
}
The onTap method is never called….It goes into the if statement..See image:

It’s failing to recognize the touch because it’s being tapped in a
UIViewanimation block.Try adding
UIViewAnimationOptionAllowUserInteractionto the options parameter when animating.EDIT
The problem is that the actual position of the
UIView‘s layer is at the final destination. What you want to do is check if itspresentationLayeris at the position which was tapped.To solve this, you could add the gesture to the main view instead of the actual label, and on tap check if the touch location is within the label’s
presentationLayer: