【问题标题】:setStatusBarHidden(_:withAnimation:) deprecated in iOS 9在 iOS 9 中不推荐使用 setStatusBarHidden(_:withAnimation:)
【发布时间】:2015-12-24 20:17:12
【问题描述】:

我看到在 iOS 9 中 setStatusBarHidden(_:withAnimation:) 现在已弃用,文档说改用 [UIViewController prefersStatusBarHidden] 但是如果我仍然想用幻灯片动画隐藏状态栏,那么在 iOS 9 中还有什么选择?

【问题讨论】:

    标签: ios swift ios9 statusbar


    【解决方案1】:

    参考preferredStatusBarUpdateAnimation

    动图

    代码

    class ViewController: UIViewController {
        var isHidden:Bool = false{
            didSet{
                UIView.animate(withDuration: 0.5) { () -> Void in
                    self.setNeedsStatusBarAppearanceUpdate()
                }  
             }
        }
        @IBAction func clicked(sender: AnyObject) {
            isHidden = !isHidden
        }
        override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation{
            return .slide
        }
        override var prefersStatusBarHidden: Bool{
            return isHidden
        }
     }
    

    【讨论】:

    • 我的没有动画,即使它在瞄准块中。有什么想法吗?
    • 它是否适用于“基于控制器的状态栏外观”= NO?
    • 没有测试,但是我猜这个键为NO时不起作用
    • Mime 在设置“基于控制器的状态栏外观”= YES 后工作。谢谢!
    • 如果您需要View controller-based status bar appearance = NO,这可能会有所帮助:*.com/a/41294874/611879
    【解决方案2】:

    斯威夫特 3

    • 计算变量已替换某些函数
    • animate 函数已更新语法

    class ViewController: UIViewController {
    
        var isHidden:Bool = false
        @IBAction func clicked(sender: AnyObject) {
            isHidden = !isHidden
            UIView.animate(withDuration: 0.5) { () -> Void in
                self.setNeedsStatusBarAppearanceUpdate()
            }
        }
    
        override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
            return UIStatusBarAnimation.slide
        }
        override var prefersStatusBarHidden: Bool {
            return isHidden
        }
    }
    

    【讨论】:

      【解决方案3】:

      通过将更新移至 didSetSwift 3 语法),我已经清理了 Leo 的惊人答案。

      class ViewController: UIViewController {
      
          @IBAction func clicked(sender: AnyObject) {
              statusBarHidden = !statusBarHidden
          }
      
          var statusBarHidden = false {
              didSet {
                  UIView.animate(withDuration: 0.5) { () -> Void in
                      self.setNeedsStatusBarAppearanceUpdate()
                  }
              }
          }
      
          override var prefersStatusBarHidden: Bool {
              return statusBarHidden
          }
      
          override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
              return .slide
          }
      }
      

      【讨论】:

      • 我希望我能记得不时使用 didSet...我只是习惯了我以前的编码方式,但这好多了:)
      【解决方案4】:

      如果你正在使用 Objective C 进行编码,这里是解决方案 :)(Leo 的 Objective C 版本 :P 谢谢哥们!!!)

      声明一个变量

      bool isHidden;
      isHidden = false;//in viewDidload()
      

      然后在你想隐藏状态栏的时候加上这段代码

      isHidden = true;
      [UIView animateWithDuration:0.6 animations:^{
          [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];
      }];
      

      然后添加这两个方法

      -(UIStatusBarAnimation) preferredStatusBarUpdateAnimation
      {
      return UIStatusBarAnimationFade;
      }
      
      -(BOOL) prefersStatusBarHidden
      { return isHidden;}
      

      希望你的问题能得到解决(微笑)

      【讨论】:

        【解决方案5】:
        • SWIFT 3 替代方案

        大家好,为 Swift 3 找到了一种更简洁的处理方式,方法是使用私有 var 与每个覆盖进行配对。 我的原帖:https://*.com/a/42083459/7183483

        但这是它的要点:

        这是一个sn-p:

        override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
            get {
                return .slide
            }
        }
        
        private var statusBarStyle : UIStatusBarStyle = .default
        
        override var preferredStatusBarStyle: UIStatusBarStyle {
            get {
                return statusBarStyle
            }
        }
        
        private var statusBarStatus : Bool = false
        
        override var prefersStatusBarHidden: Bool {
            get {
                return statusBarStatus
            }
        }
        

        然后我可以在这样的函数中调用它:(这是我的示例之一,因此请忽略自定义函数)。

        func sliderView(sliderView: SliderView, didSlideToPlace: CGFloat, within: CGFloat) {
        
            let val = (within - (didSlideToPlace - sliderView.upCent))/(within)
            print(val)
            //Where you would change the private variable for the color, for example.
            if val > 0.5 {
                statusBarStyle = .lightContent
            } else {
                statusBarStyle = .default
            }
            UIView.animate(withDuration: 0.5, animations: {
                sliderView.top.backgroundColor = UIColor.black.withAlphaComponent(val)
                self.coverLayer.alpha = val
                self.scroll.backgroundColor = colors.lightBlueMainColor.withAlphaComponent(val)
            }, completion: {
                value in
                //If you do not call setNeedsStatusBarAppearanceUpdate() in an animation block, the animation variable won't be called it seems.
                UIView.animate(withDuration: 0.4, animations: {
        
                    self.animating = true
        
                    //Where you set the status for the bar (your part of the solution)
                    self.statusBarStatus = false
        
                    //Then you call for the refresh
                    self.setNeedsStatusBarAppearanceUpdate()
                })
            })
        }
        

        【讨论】:

        • 这是一个很好的解决方案。我没想过让状态隐藏标志动态化。