// 各個主頁面類 // XQWBHomeViewController.swift // XQWBDiscoverViewController.swift // XQWBMessageViewController.swift // XQWBMineViewController.swift // XQWBBaseViewController.swift // 根據須要建立基類 // XQWBMainViewController.swift (繼承 UITabBarController) // XQWBBaseViewController.swift (繼承 ViewController) // XQWBNavigationController.swift (繼承 NavigationController)
window = UIWindow() window?.backgroundColor = UIColor.white window?.rootViewController = XQWBMainViewController() window?.makeKeyAndVisible()
5.1 聲明一個方法,用來建立控制器信息的字典數組,而且經過遍歷數組建立控制器,給UITabBarController的viewControllers賦值git
// 設置全部字控制器 func setupChildControllers() { let array = [ ["clsName":"XQWBHomeViewController", "title":"首頁", "imgName":"home"], ["clsName":"XQWBDiscoverViewController", "title":"發現", "imgName":"discover"], ["clsName":"UIViewController", "title":"", "imgName":""], // 第二個控制器使用UIViewcontroller 實現佔位做用 ["clsName":"XQWBMessageViewController", "title":"消息", "imgName":"message_center"], ["clsName":"XQWBMineViewController", "title":"個人", "imgName":"profile"] ] var arrayM = [UIViewController]() for dict in array { // 注意: swift 3.0之後循環只能使用for_in 來實現,普通的for循環由於 i++的語法被廢除而沒法使用 arrayM.append(controller(dict: dict)) } viewControllers = arrayM }
5.2 根據控制器信息的字典和反射原理使用字符串建立UIViewController,建立NavigationController,而且返回swift
// 根據字典建立一個子控制器 func controller(dict:[String:String]) -> UIViewController { // 1. 取字典信息 // 這裏使用guard let 守護一下,能夠避免去到空值,另外能夠設置中間的站位UIViewcontroller guard let clsName = dict["clsName"], let title = dict["title"], let imgname = dict["imgName"], let cls = NSClassFromString(Bundle.main.nameSpace + "." + clsName) as? UIViewController.Type else { return UIViewController() } // 2. 建立視圖控制器 let vc = cls.init() // 2.1 設置標題 vc.title = title; // 2.2 設置圖像 vc.tabBarItem.image = UIImage(named: "tabbar_" + imgname); vc.tabBarItem.selectedImage = UIImage(named: "tabbar_" + imgname + "_highlighted")?.withRenderingMode(.alwaysOriginal) // 3. 設置nav let nav = XQWBNavigationController(rootViewController: vc) // 4. 設置tabbar 字體 vc.tabBarItem.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.orange], for: .highlighted) // 設置選擇狀態下的圖片顏色 vc.tabBarItem.setTitleTextAttributes([NSFontAttributeName: UIFont.systemFont(ofSize: 14)], for: []) // 設置文字大小隻能在normal 狀態下設置 return nav }
6.1 聲明一個懶加載的屬性按鈕數組
/// 編寫按鈕 lazy var composeBtn:UIButton = { // 設置按鈕圖片 let btn = UIButton.cz_imageButton("tabbar_compose_icon_add", backgroundImageName: "tabbar_compose_button") // 設置按鈕點擊事件 btn?.addTarget(self, action: #selector(composeStatus), for: .touchUpInside) return btn!; }()
6.2 設置"寫微博"按鈕的frame架構
/// 設置寫按鈕 func setupComposeBtn() { // 添加到視圖 tabBar.addSubview(composeBtn) // 設置按鈕位置 let count = CGFloat(childViewControllers.count) let width = tabBar.bounds.width / count - 1; // 這裏-1 是讓按鈕變寬,防止點擊到默認的佔位按鈕,跳轉到佔位Viewcontroller composeBtn.frame = tabBar.bounds.insetBy(dx: 2 * width, dy: 0) }
6.3 實現"寫微博"按鈕的點擊事件app
// FIXME: 寫微博沒有實現 @objc func composeStatus() { print("寫微博") }
7.1 在 BaseViewController 中添加懶加載的UINavigationBar和UINavigationItemdom
// 自定義導航條 lazy var navigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: UIScreen.cz_screenWidth(), height: 64)) // 自定義導航項 之後設置導航欄內容 用navItem lazy var navItem = UINavigationItem()
7.2 添加 setupUI() 方法,設置基本UI,可讓子類重寫ide
func setupUI() { // 隨機背景顏色 view.backgroundColor = UIColor.cz_random() // 添加導航條 view.addSubview(navigationBar) // 設置item navigationBar.items = [navItem] // 設置navbar 的渲染顏色 navigationBar.barTintColor = UIColor.cz_color(withHex: 0xF6F6F6) // 設置navbar title 字體顏色 navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.darkGray] }
7.3 重寫 title 的disSet 方法,設置navItem.title測試
override var title: String? { didSet { navItem.title = title } }
7.4 在HomeViewController和DemoViewController中重寫setupUI()方法,設置BarButtonItem測試push/pop字體
// 重寫 setupUI() override func setupUI() { super.setupUI() navItem.rightBarButtonItem = UIBarButtonItem(title: "下一個", target: self, action: #selector(showNext)) } // 實現點擊按鈕方法 @objc func showNext() { let vc = XQWBDemoViewController() navigationController?.pushViewController(vc, animated: true) }
7.5 重寫func pushViewController(_ viewController: UIViewController, animated: Bool) {} 方法,設置當push的時候隱藏tabBar,設置返回按鈕顯示的文字ui
override func pushViewController(_ viewController: UIViewController, animated: Bool) { if childViewControllers.count > 0 { // 設置push後隱藏tabbar viewController.hidesBottomBarWhenPushed = true // 判斷控制器類型 if let vc = viewController as? XQWBBaseViewController { var title = "返回" if childViewControllers.count == 1 { title = childViewControllers.first?.title ?? "返回" } vc.navItem.leftBarButtonItem = UIBarButtonItem(title: title, target: self, action: #selector(popToParent), isBackButton: true) } } super.pushViewController(viewController, animated: animated) }
次日的內容主要自定義了UItabBarController 和 UINavigationBar, 而且處理了push隱藏tabbar和返回按鈕的文字