[英]UIView added as an UIWindow subview doesn't respond to taps
我添加了一個包含UITapGestureRecognizer
的UIView
作為我的關鍵窗口的子視圖。 它顯示正確,但是當我點擊我的視圖時,目標方法不會被觸發。 我什至嘗試用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.