简体   繁体   中英

UITapGestureRecognizer not working on UIView

I've read multiple solutions here on SO, but they all don;t seem to work in my case.

I've got a class NotificationBar: .h file:

@interface NotificationBar : UIView <UIGestureRecognizerDelegate>

@property (strong, nonatomic) UILabel *messageLabel;

- (id)initWithFrame:(CGRect)frame message:(NSString *)message;

- (void) show:(int)duration;

@end

.m file:

#import "NotificationBar.h"

@implementation NotificationBar

@synthesize messageLabel;

- (id)initWithFrame:(CGRect)frame message:(NSString *)message
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.alpha = 0;
        self.backgroundColor = [UIColor cabmanBlue];
        self.userInteractionEnabled = YES;

        self.messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.bounds.origin.x + 5, 0 , self.bounds.size.width - 10, self.bounds.size.height)];
        [self.messageLabel setBackgroundColor:[UIColor clearColor]];
        [self.messageLabel setTextColor:[UIColor whiteColor]];
        [self.messageLabel setFont:[UIFont boldSystemFontOfSize:14]];
        [self.messageLabel setNumberOfLines:2];
        self.messageLabel.text = message;
        [self addSubview:messageLabel];

        UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss:)];
        tapRec.delegate = self;
        tapRec.cancelsTouchesInView = NO;
        [self addGestureRecognizer:tapRec];
    }
    return self;
}

- (void) show:(int)duration
{
    [[[[[UIApplication sharedApplication] keyWindow] subviews] lastObject] addSubview:self];
    [UIView animateWithDuration:0.5 animations:^{ self.alpha = 1; } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.5 delay:duration options:UIViewAnimationOptionCurveLinear animations:^{ self.alpha = 0;} completion:^(BOOL finished)
         {
             if(finished) [self removeFromSuperview];
         }];
    }];
}

- (void) dismiss:(UITapGestureRecognizer *)gesture
{
    [self.layer removeAllAnimations];
    [UIView animateWithDuration:0.5 animations:^{ self.alpha = 0; } completion:^(BOOL finished) {
        if(finished)
        {
            [self removeFromSuperview];
        }
    }];
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

@end

And I use the class in the following way:

- (void) displayNotificationMessage:(NSString *)message withSound:(BOOL) withSound
{
    UIView *topView = [self.window.subviews lastObject];
    [[[NotificationBar alloc] initWithFrame:CGRectMake(topView.bounds.origin.x,
                                                                             64,
                                                                             topView.bounds.size.width,
                                                                             40)
                            message:message] show:10];

    if(withSound) AudioServicesPlaySystemSound(1007);
}

The view is always presented and shown. The dismiss function isn't triggered and it seems it doesn't respond to anything. displayNotificationMessage is placed in AppDelegate. displayNotificationMessage is some times used when a viewcontroller with a mapview is displayed or in a UITableViewController. You could say it has to work the same way as UIAlertView: always presented no matter in which screen the user is.

Does anyone see an error or something? Thank in advance!

Your UILabel takes over almost your entire view bounds:

self.messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.bounds.origin.x + 5, 0 , self.bounds.size.width - 10, self.bounds.size.height)];

You may try reducing it's size and then see if the gesture works in the other locations or you can try adding the gesture to the label

[self.messageLabel addGestureRecognizer:singleTap];  

I just tried your code on a custom UIView and it works just fine. Having the UILabel as a subview has no effect, it responds well. To me it looks like you probably have either another UIView put over this one (which makes this one buried and therefore unresponsive) or you have another Tap Gesture registered in your superview .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM