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
    }
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM