Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIView added as an UIWindow subview doesn't respond to taps

I've added a UIView containing a UITapGestureRecognizer as my key window's subview. It shows properly, however when I tap my view, the target method is not fired. I've even tried to replace the gesture recognizer with a UIButton, still to no avail.

Here is my code.

NotificationView.h

#import <UIKit/UIKit.h>

typedef NS_ENUM(int, NotificationKind) {
    NotificationKindActivity,
    NotificationKindReply,
};

@interface NotificationView : UIView {

    NotificationKind currentNotificationKind;

}

-(id)initWithMessage:(NSString*)message andColor:(UIColor*)color andKind:(NotificationKind)kind;
-(void)show;

@end

NotificationView.m

#import "NotificationView.h"

@implementation NotificationView

- (id)initWithMessage:(NSString*)message andColor:(UIColor*)color andKind:(NotificationKind)kind
{
    self = [super initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), 60)];
    if (self) {
        // Initialization code
        [self setAlpha:0];
        [self setBackgroundColor:color];
        [self setUserInteractionEnabled:YES];


        currentNotificationKind = kind;

        UILabel *label = [[UILabel alloc] initWithFrame:self.bounds];
        [label setNumberOfLines:0];
        [label setFont:[UIFont fontWithName:@"Roboto-Italic" size:20]];
        [label setTextColor:[UIColor whiteColor]];
        [label setTextAlignment:NSTextAlignmentCenter];
        [label setPreferredMaxLayoutWidth:290];
        [label setText:message];
        [label setUserInteractionEnabled:YES];
        [self addSubview:label];

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(notificationTapped)];
        [tap setNumberOfTapsRequired:1];
        [self addGestureRecognizer:tap];

        [[[UIApplication sharedApplication] keyWindow] addSubview:self];

    }
    return self;
}

-(void)show{
    [UIView animateWithDuration:0.3 animations:^{

        [self setAlpha:1];

    } completion:^(BOOL finished) {

        [UIView animateWithDuration:0.3 delay:3 options:UIViewAnimationOptionCurveLinear animations:^{
            [self setAlpha:0];

        } completion:^(BOOL finished) {
            [self removeFromSuperview];
        }];

    }];
}

-(void)notificationTapped{

    DDLogDebug(@"Notification tapped!");

}

@end
like image 562
Martin Herman Avatar asked Aug 18 '14 14:08

Martin Herman


1 Answers

When this happens to me it's usually because I screwed up my UIView frame. I see all the content as expected because my UIView isn't clipping to bounds, but I can't interact with anything because my taps are outside the bounds of the UIView.

My simple test is to change the background color of the UIView and see if it covers the area I expect or if I screwed up size/placement somehow.

I used to pound my head against the wall with this issue, struggling for hours, but I've done it so many times now it's 5min fix of "Oh that again".

Edit:

Then I'd look at your show code. Your calling code isn't here, but if I'm to assume your are just using your show code and your view is only on screen for 3 seconds, then that's you problem.

As Justin mentioned (comment above) and Apple's docs

During an animation, user interactions are temporarily disabled for all views involved in the animation, regardless of the value in this property. You can disable this behavior by specifying the UIViewAnimationOptionAllowUserInteraction option when configuring the animation.

Since the entire time your view is on the screen it's part of an animation block, all interaction will be disable for the entire time it's visible. I've never quite tested the delay bit and whether animation was disabled during that piece, but it would not surprise me animation is disabled during the delay. The second animation is still inside the primary animation block, so I'd assume animations will be blocked until both are complete.

like image 68
DBD Avatar answered Nov 03 '22 00:11

DBD