繁体   English   中英

添加为 UIWindow 子视图的 UIView 不响应点击

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

我添加了一个包含UITapGestureRecognizerUIView作为我的关键窗口的子视图。 它显示正确,但是当我点击我的视图时,目标方法不会被触发。 我什至尝试用UIButton替换手势识别器,但仍然无济于事。

这是我的代码。

通知视图.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

通知视图.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

当我遇到这种情况时,通常是因为我搞砸了UIView框架。 我按预期看到所有内容,因为我的UIView没有剪裁到边界,但我无法与任何内容交互,因为我的点击超出了UIView的边界。

我的简单测试是更改UIView的背景颜色,看看它是否覆盖了我期望的区域,或者我是否以某种方式搞砸了尺寸/位置。

我曾经因为这个问题把我的头撞在墙上,挣扎了几个小时,但我已经做了很多次了,现在是“哦,又一次”的 5 分钟修复。

编辑:

然后我会看看你的show代码。 你的调用代码不在这里,但如果我假设你只是使用你的show代码并且你的视图只在屏幕上显示 3 秒,那么这就是你的问题。

正如贾斯汀提到的(上面的评论)和苹果的文档

在动画期间,无论此属性中的值如何,动画中涉及的所有视图都将暂时禁用用户交互。 您可以通过在配置动画时指定 UIViewAnimationOptionAllowUserInteraction 选项来禁用此行为。

由于您的视图在屏幕上的整个时间都是动画块的一部分,因此在它可见的整个时间内所有交互都将被禁用。 我从来没有完全测试过delay位以及动画在那个片段中是否被禁用,但是在延迟期间动画被禁用我不会感到惊讶。 第二个动画仍然在主动画块内,所以我假设动画将被阻止,直到两者都完成。

根据@DBD 的建议更新了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 setClipsToBounds: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];
        [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 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{

        [self setAlpha:1];

    } completion:nil];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{

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

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

    });


}

-(void)notificationTapped{

    DDLogDebug(@"Notification tapped!");

}

@end

假设首先调用 makeKeyAndVisible,我最终能够创建一个全屏子视图,通过将其添加到应用程序的 keyWindow 来接受手势:

myView.hidden = YES;
[[[UIApplication sharedApplication] keyWindow] addSubview:myView];

然后在状态栏上方显示它:

[[UIApplication sharedApplication] keyWindow].windowLevel = UIWindowLevelStatusBar + 1;
myView.hidden = NO;

并将其改回:

[[UIApplication sharedApplication] keyWindow].windowLevel = UIWindowLevelNormal;
myView.hidden = YES;

这只会更改应用程序主窗口(包括其所有子视图)在窗口层次结构中的位置。 希望有帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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