iOS Status Bar 的隐藏

转载http://jumpingfrog0.github.io/2016/2016-03-26-status-bar-hidden/

Status Bar 的正常隐藏

view-controllers 控制 status bar 的隐藏

在iOS 9中,status bar 的隐藏默认是通过 view-controlls 控制的,即每个控制器决定是否隐藏 status bar 。

只需在 controller 中重载 prefersStatusBarHidden 函数

override func prefersStatusBarHidden() -> Bool {
    return true
}

  全局控制 status bar 的隐藏

如果想要全局控制,只需两步:

  • 在Info.plist中,添加属性 View controller-based status bar appearance 为 NO
  • 添加如下代码

    UIApplication.sharedApplication().statusBarHidden = true
    

      

  • 如果想改成每个控制器自行控制,将 View controller-based status bar appearance 为 YES即可

Status Bar 隐藏不了的情况

但是,有时候也会有意外发生,上述方法并不能如愿隐藏 status bar ,那就是 ParentViewController 中添加一个全屏的 ChildViewController ,此时想用ChildViewController 来控制状态栏时 ,就会失效,即使 ChildViewController 中的prefersStatusBarHidden方法返回的是YES,也无法隐藏 status bar 。

解决办法是:重载 childViewControllerForStatusBarHidden方法

如果你想要让你的 container view controller 的 child view controller 控制 status bar 的隐藏状态的话,就重载该方法,决定使用哪个 child view controller 来控制 隐藏/非隐藏 的状态。如果返回 nil 或不重载该方法,就用它自己来控制 status bar 的状态。可以通过调用 setNeedsStatusBarAppearanceUpdate 方法来改变该方法返回的值,即再调用该方法一次。

class StatusBarHiddenParentController: UIViewController {
    
    var childController: StatusBarHiddenChildController?
    override func viewDidLoad() {
        super.viewDidLoad()
        childController = StatusBarHiddenChildController.fromStoryboard("Main")
        addChildViewController(childController!)
        view.addSubview(childController!.view)
        setNeedsStatusBarAppearanceUpdate()
    }
    override func childViewControllerForStatusBarHidden() -> UIViewController? {
        return childController
    }
    
    override func prefersStatusBarHidden() -> Bool {
        return false
    }
}
class StatusBarHiddenChildController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    override func prefersStatusBarHidden() -> Bool {
        return true
    }
}

  

上述代码最终能将状态栏隐藏,即使在 StatusBarHiddenParentController 中的prefersStatusBarHidden返回的是NO

注意:因为childViewControllerForStatusBarHidden会比viewDidLoad 先调用,所以在viewDidLoad中要调用setNeedsStatusBarAppearanceUpdate

有时候我们需要关闭控制器视图,如下列三种情况:

  • 将控制器从navigationController的堆栈中pop出去
  • 将present出来的控制器dismiss掉
  • 将子控制器从父控制器中移除

push 和 present 两种方式展示的 view controller 在 pop 和 dismiss 时都能够自动还原 status bar 的状态。但是,把子控制器从父控制器中移除时,就会出现奇怪的问题, status bar并不能自动还原,因此还需要特别处理。

我们可以设置一个Bool变量 statusBarHidden 用来记录目前 statusBar 是否隐藏,在 prefersStatusBarHidden 函数中返回 statusBarHidden值。在要移除子控制器的函数中做两步操作:

  1. 先将 statusBarHidden 设置为 False, 并调用 setNeedsStatusBarAppearanceUpdate 刷新状态栏
  2. 再将子控制器移除。
class StatusBarHiddenRemoveWayChildController: UIViewController {
    
    var statusBarHidden: Bool = true
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let removeButton = UIButton(frame: CGRectMake(30, 80, 100, 30))
        removeButton.setTitle("remove", forState: .Normal)
        removeButton.addTarget(self, action: "remove", forControlEvents: .TouchUpInside)
        view.addSubview(removeButton)
    }
    
    // 1. set `statusBarHidden` into `false`, and then refresh status bar
    // 2. remove from parent controller
    
    func remove() {
        statusBarHidden = false
        setNeedsStatusBarAppearanceUpdate()
        
        view.removeFromSuperview()
        removeFromParentViewController()
    }
    
    override func prefersStatusBarHidden() -> Bool {
        return statusBarHidden
    }
}

  

滚动ScrollView或TableView时隐藏Status Bar和Navigation Bar

京东和淘宝客户端的商品搜索结果页面,在滚动时可以隐藏 status bar 和 navigation bar ,我自认为这是一个很好的设计,身为一个有追求的程序员,这个功能的实现那当然也不能放过啦~~

NavigationController 有一个属性 hidesBarsOnSwipe,可以实现轻扫时隐藏 navigation bar ,与之对应的手势是它的另一个属性barHideOnSwipeGestureRecognizer,只要给这个手势添加一个方法来控制 status bar ,就可以实现同时隐藏 status bar 和 navigation bar 了。

class StatusBarAndNavigationBarHiddenOnSwipeController: UITableViewController {
    
    var hideStatusBar = false
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor.grayColor()
        
        navigationController?.barHideOnSwipeGestureRecognizer.addTarget(self, action: "swipe:")
        navigationController?.hidesBarsOnSwipe = true
    }
    
    override func prefersStatusBarHidden() -> Bool {
        return hideStatusBar
    }
    
    func swipe(recognizer: UISwipeGestureRecognizer) {
        
        hideStatusBar = navigationController?.navigationBar.frame.origin.y < 0
        
        UIView.animateWithDuration(0.2) { () -> Void in
            
            self.setNeedsStatusBarAppearanceUpdate()
        }
    }
    
    override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
        return .Slide
    }
}

  

 

转载于:https://www.cnblogs.com/wuyang-li/p/10972131.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值