如何防止UIWindow成为关键窗口?

时间:2016-06-30 07:06:26

标签: ios uikit uiwindow

当我显示UIAlertController的提醒时,提醒本身会显示在新窗口中。 (至少现在)当警报窗口解散时,系统似乎设置了一个随机窗口键窗口。

我正在展示一个新的横幅"窗口在状态栏上呈现一些横幅(AppStore兼容性不在此处),通常,这个" banner"窗口成为下一个关键窗口,并在用户输入和第一响应者管理方面造成许多问题。

所以,我想阻止这个" banner"窗口成为关键窗口,但我无法弄清楚如何。现在,作为一种解决方法,我只是将我的主窗口重新设置为一个关键窗口,并且#34; banner"窗口成为关键窗口。但它并没有感觉真的很好。

如何防止窗口成为关键窗口?

3 个答案:

答案 0 :(得分:1)

作为一种解决方法,我们可以在" banner"之后再次设置主窗口密钥。窗口变成这样的关键。

class BannerWindow: UIWindow {
    weak var mainWindow: UIWindow?
    override func becomeKeyWindow() {
        super.becomeKeyWindow()
        mainWindow?.makeKeyWindow()
    }
}

答案 1 :(得分:0)

我多年来一直试图解决这个问题。我终于报告了雷达:http://www.openradar.me/30064691

我的解决方法看起来像这样:

// a UIWindow subclass that I use for my overlay windows
@implementation GFStatusLevelWindow

...

#pragma mark - Never become key
// http://www.openradar.me/30064691

// these don't actually help
- (BOOL)canBecomeFirstResponder
{
    return NO;
}

- (BOOL)becomeFirstResponder
{
    return NO;
}


- (void)becomeKeyWindow
{
    LookbackStatusWindowBecameKey(self, @"become key window");
    [[self class] findAndSetSuitableKeyWindow];
}

- (void)makeKeyWindow
{
    LookbackStatusWindowBecameKey(self, @"make key window");
}

- (void)makeKeyAndVisible
{
    LookbackStatusWindowBecameKey(self, @"make key and visible window");
}

#pragma mark - Private API overrides for status bar appearance

// http://www.openradar.me/15573442
- (BOOL)_canAffectStatusBarAppearance
{
    return NO;
}

#pragma mark - Finding better key windows

static BOOL IsAllowedKeyWindow(UIWindow *window)
{
    NSString *className = [[window class] description];
    if([className isEqual:@"_GFRecordingIndicatorWindow"])
        return NO;
    if([className isEqual:@"UIRemoteKeyboardWindow"])
        return NO;
    if([window isKindOfClass:[GFStatusLevelWindow class]])
        return NO;

    return YES;
}

void LookbackStatusWindowBecameKey(GFStatusLevelWindow *self, NSString *where)
{
        GFLog(GFError, @"This window should never be key window!! %@ when in %@", self, where);
        GFLog(GFError, @"To developer of %@: This is likely a bug in UIKit. If you can get a stack trace at this point (by setting a breakpoint at LookbackStatusWindowBecameKey) and sending that stack trace to nevyn@lookback.io or support@lookback.io, I will report it to Apple, and there will be rainbows, unicorns and a happier world for all :) thanks!", [[NSBundle mainBundle] gf_displayName]);
}

+ (UIWindow*)suitableWindowToMakeKeyExcluding:(UIWindow*)notThis
{
    NSArray *windows = [UIApplication sharedApplication].windows;
    NSInteger index = windows.count-1;

    UIWindow *nextWindow = [windows objectAtIndex:index];
    while((!IsAllowedKeyWindow(nextWindow) || nextWindow == notThis) && index >= 0) {
        nextWindow = windows[--index];
    }
    return nextWindow;
}

+ (UIWindow*)findAndSetSuitableKeyWindow
{

    UIWindow *nextWindow = [[self class] suitableWindowToMakeKeyExcluding:nil];
    GFLog(GFError, @"Choosing this as key window instead: %@", nextWindow);
    [nextWindow makeKeyWindow];
    return nextWindow;
}

答案 2 :(得分:0)

也面对这个问题。看来只需制作就足够了:

class BannerWindow: UIWindow {
    override func makeKey() {
        // Do nothing
    }
}

这样,您无需保留对先前keyWindow的引用,如果它可能会被更改,这将非常酷。

对于Objective-C,它是:

@implementation BannerWindow

- (void)makeKeyWindow {
    // Do nothing
}

@end