【问题标题】:How to prevent a UIWindow to be a key window?如何防止 UIWindow 成为关键窗口?
【发布时间】:2016-06-30 07:06:25
【问题描述】:

当我使用UIAlertController 显示警报时,警报本身会显示在一个新窗口中。 (至少现在)并且当警报窗口消失时,系统似乎设置了一个随机窗口键窗口。

我正在展示一个新的“横幅”窗口以在状态栏上呈现一些横幅(AppStore 兼容性不在此处讨论),通常,此“横幅”窗口成为下一个关键窗口,并导致用户输入出现许多问题和急救人员管理。

所以,我想阻止这个“横幅”窗口成为关键窗口,但我不知道怎么做。目前,作为一种解决方法,只要“横幅”窗口成为关键窗口,我就将主窗口重新设置为关键窗口。但是感觉真的不是很好。

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

【问题讨论】:

    标签: ios uikit uiwindow


    【解决方案1】:

    作为一种解决方法,我们可以在“横幅”窗口变成这样的键时再次设置主窗口键。

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

    【讨论】:

    • 我在 iOS 14.4 上使用了这个解决方案,作为一个缺点,我发现在这个 becomeKey() 回调之后,任何文本字段都无法显示复制/粘贴栏。 DispatchQueue.main.async 调用 otherWindow?.makeKey() 似乎可以解决它,但它可能会产生其他意想不到的影响。
    【解决方案2】:

    也面临这个问题。看来只要做就够了:

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

    这样您就不需要保留对先前 keyWindow 的引用,如果它可能会被更改,这尤其酷。

    对于 Objective-C 它是:

    @implementation BannerWindow
    
    - (void)makeKeyWindow {
        // Do nothing
    }
    
    @end
    

    【讨论】:

      【解决方案3】:

      多年来,我一直在努力解决这个问题。我终于为它报了一个雷达: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;
      }
      

      【讨论】:

        猜你喜欢
        • 2011-08-28
        • 2012-08-28
        • 1970-01-01
        • 2020-06-26
        • 2019-10-13
        • 2010-12-06
        • 2014-07-01
        • 2010-09-24
        • 1970-01-01
        相关资源
        最近更新 更多