iOS学习笔记(十三):TabBarController做根视图控制器后状态栏不显示的解决办法

在ITMO访学写结课大作业时,模仿HduIn的架构将一个TabBar作为rootViewController,在里面放入了3个子controller,并且每个子controller套了一个NavigationController,以便后续对controller的push操作:

//
//  MainViewController.swift
//

import UIKit

class MainViewController: UITabBarController {

    override func viewDidLoad() {
        initViewControllers()
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
    }
    
    func initViewControllers() {
        let VC1 = MessageViewController()
        let VC2 = FriendsViewController()
        let VC3 = MineViewController()
        
        creatTabbarView(viewController: VC1, image: "chat-barIcon", selectImage: "chat-barIcon-selected", title: "消息")
        creatTabbarView(viewController: VC2, image: "contacts-barIcon", selectImage: "contacts-barIcon-selected", title: "通讯录")
        creatTabbarView(viewController: VC3, image: "me-barIcon", selectImage: "me-barIcon-selected", title: "我的")
        let subViewControllers = [VC1, VC2, VC3]
        let navigationViewControllers = subViewControllers.map {
            subViewController -> UIViewController in
            subViewController.view.frame = self.view.frame
            subViewController.view.bounds = self.view.bounds
            subViewController.extendedLayoutIncludesOpaqueBars = true
            
            return BaseNavigationController(rootViewController: subViewController)
        }
        self.viewControllers = navigationViewControllers
        self.tabBar.tintColor = UIColor(red: 85/255, green: 183/255, blue: 55/255, alpha: 1)
    }
    
    func creatTabbarView(viewController:UIViewController, image:String, selectImage:String, title:String) {
        // alwaysOriginal 始终绘制图片原始状态,不使用Tint Color。
        viewController.tabBarItem.image = UIImage(named: image)?.withRenderingMode(.alwaysOriginal)
        viewController.tabBarItem.selectedImage = UIImage(named: selectImage)?.withRenderingMode(.alwaysOriginal)
        viewController.title = title
    }
    
}

//
//  BaseNavigationController.swift
//

import UIKit

class BaseNavigationController: UINavigationController {

    // MARK: LifeCycle
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        
    }
    
    override init(navigationBarClass: AnyClass?, toolbarClass: AnyClass?) {
        super.init(navigationBarClass: navigationBarClass, toolbarClass: toolbarClass)
    }
    
    override init(rootViewController: UIViewController) {
        super.init(rootViewController: rootViewController)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    // MARK: View LifeCycle
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationBar.barTintColor = UIColor.white
        self.navigationBar.tintColor = UIColor.black
        self.navigationBar.barStyle = .default
        navigationBar.isTranslucent = false
        navigationBar.shadowImage = UIImage()
    }
    
    override var preferredStatusBarStyle : UIStatusBarStyle {
        return .lightContent
    }

    override func pushViewController(_ viewController: UIViewController, animated: Bool)
    {
        if children.count > 0 {
            viewController.hidesBottomBarWhenPushed = true
        }
        super.pushViewController(viewController, animated: animated)
    }
}

此时运行后却发现系统状态栏缺失。上网了解后才明白,如果是自定义UITabBarController的情况,需要在BaseNavigationController中重写childForStatusBarStyle属性,使得子控制器的preferredStatusBarStyle的属性生效:

//重写此方法让 preferredStatusBarStyle 响应
    override var childForStatusBarStyle: UIViewController? {
        return self.topViewController
    }

究其原因,直接上一位博主博客的截图:

总结一下,如果在工程中自定义了TabBarController或者NavigationController作为ViewController的容器,需要重写这个方法来应用对状态栏属性的设置。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注