【问题标题】:Restore status bar state after closing second UIWindow关闭第二个 UIWindow 后恢复状态栏状态
【发布时间】:2017-07-13 00:00:30
【问题描述】:

主要的UIWindow 包含MainViewController,它使用lightContent 作为preferredStatusBarStyle。我创建了第二个UIWindow 实例来显示PopupViewController,它使用default 作为preferredStatusBarStyle。

当我用PopupViewController 显示第二个UIWindow 时,状态栏样式更改为default,但是当我隐藏它时,样式不会变回lightContent。

同样的问题适用于我在弹出窗口中有隐藏状态栏的 VC 的情况 - 当弹出窗口被解除时状态栏不显示。

新UIWindow创建:

// Prepare window to show dialog box in
newWindow = UIWindow(frame: UIScreen.main.bounds)
newWindow?.windowLevel = 3

// Overlay new window
newWindow?.makeKeyAndVisible()
self.mainWindow.windowLevel = 1
self.mainWindow.endEditing(true)
newWindow?.isHidden = false

// Display dialog
newWindow?.rootViewController = PopupViewController()

新的UIWindow 解雇:

UIView.animate(
    withDuration: 1.0,
    delay: 0,
    usingSpringWithDamping: 1,
    initialSpringVelocity: 0,
    options: .curveEaseOut,
    animations: { [weak self] in
        self?.newWindow?.alpha = 0
    },
    completion: { [weak self] _ in
        self?.newWindow?.windowLevel = 0
        self?.newWindow?.rootViewController = nil
        self?.newWindow?.alpha = 1
        self?.mainWindow.makeKeyAndVisible()
    }
)

谢谢!

编辑:弹窗随时可能出现,我不知道当时哪个VC活跃

【问题讨论】:

    标签: ios swift uiwindow


    【解决方案1】:

    更改 ViewWillAppear 上的状态栏样式

    override func viewWillAppear(_ animated: Bool) {
        UIApplication.shared.statusBarStyle = .lightContent
    }
    

    【讨论】:

    • 弹出窗口可以出现在随机 VC 上。手动设置样式对我来说有点 hacky。我想有办法告诉“好的,现在这个窗口又是主窗口了,这里是 rootVC,从它继承状态栏设置”。
    • 您是否在 info.plist 上将“基于控制器的状态栏外观”设置为 NO
    • 不,很遗憾我需要它基于 VC 的
    • 那么唯一的选择是您必须在每个 VC 中手动更改此设置
    【解决方案2】:
    1. 请在您更改状态栏颜色 Light 的第一个控制器上添加以下代码。

      覆盖 func viewDidAppear(_ animated: Bool) { UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.lightContent, animated: false) }

    2. 现在在您想要默认状态栏样式的第二个控制器中,输入代码:

      覆盖 func viewDidAppear(_ animated: Bool) { UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.default, animated: false) }

    通过上面的代码,你一定会得到正确的解决方案

    【讨论】:

    • 问题是弹出窗口可以随时出现,我现在不知道当时哪个 VC 处于活动状态
    【解决方案3】:

    为您的案例提供简单的解决方案

    1. 显示窗口

    为您的案例提供简单的解决方案

    1. 新的 UIWindow 创建:

      // Prepare window to show dialog box in
      newWindow = UIWindow(frame: UIScreen.main.bounds)
      newWindow?.windowLevel = 3
      
      // Overlay new window
      newWindow?.makeKeyAndVisible()
      self.mainWindow.windowLevel = 1
      self.mainWindow.endEditing(true)
      newWindow?.isHidden = false
      
      // Display dialog
      newWindow?.rootViewController = PopupViewController()
      // Now you can change status bar style default or other style
      UIApplication.shared.statusBarStyle = .default
      
    2. 新的 UIWindow 关闭:

      UIView.animate(
          withDuration: 1.0,
          delay: 0,
          usingSpringWithDamping: 1,
          initialSpringVelocity: 0,
          options: .curveEaseOut,
          animations: { [weak self] in
              self?.newWindow?.alpha = 0
              // Revert back to default
              UIApplication.shared.statusBarStyle = .lightContent
          },
          completion: { [weak self] _ in
              self?.newWindow?.windowLevel = 0
              self?.newWindow?.rootViewController = nil
              self?.newWindow?.alpha = 1
              self?.mainWindow.makeKeyAndVisible()
          }
      )
      

    【讨论】:

    • 这很好,因为与其他建议的解决方案不同,这个解决方案可以在弹出式 VC 中处理所有问题,但看起来 UIApplication.shared.setStatusBarStyle() 自 9.0 起已弃用
    • @Andrejs Mironovs UIApplication.shared.statusBarStyle = .lightContent 我已经在 iOS 10 中工作,这段代码运行良好,请检查一下。
    【解决方案4】:

    我要找的是UIViewController.setNeedsStatusBarAppearanceUpdate()。告诉 VC 状态栏外观已更改,需要恢复是一种方便的方法。

    // make main window key but transparent
    self.mainWindow.alpha = 0
    self.newWindow?.windowLevel = 0
    self.newWindow?.alpha = 1
    self.mainWindow.makeKey()
    
    // restore status bar appearance  
    self.mainWindow.rootViewController!.setNeedsStatusBarAppearanceUpdate()
    
    // Fade in main window with (status bar is in proper state at this moment)
    UIView.animate(
            withDuration: 0.9,
            delay: 0,
            usingSpringWithDamping: 1,
            initialSpringVelocity: 0,
            options: .curveEaseIn,
            animations: { [weak self] in
                self?.mainWindow.alpha = 1
            },
            completion: { [weak self] _ in
                // destroy popup VC
                self?.newWindow?.rootViewController = nil
            }
    )
    

    Here is useful article on this subject

    谢谢大家!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-02
      • 1970-01-01
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多