iOS 基础:逻辑清晰地使用 UITabBarController

2,389 阅读1分钟

阅读本文的先决条件

  • 了解 Swift 4.0+ 基础语法
  • 了解 UITabBarController 的基本用法

正文

TabBarViewModel 的设计

由于 TabBarController 本身是一个控制器容器,一般不需要有自己的 View,也不需要有自己的 Model,所以我们只需要设计一个 TabBarViewModel 搭配 TabBarController 使用即可。

TabBarViewModel 的作用

这里的 TabBarViewModel 主要是负责 TabBarController 的装配,也就是 TabBarItem 的设置,以及其中子 ViewController 的初始化和绑定。

TabBarViewModel.swift

// MyTabBarViewModel.swift

import UIKit

class MyTabBarViewModel: NSObject {
    
    enum MyTabbarItem {
        case search
        case favorite
    }
    
}

extension MyTabBarViewModel.MyTabbarItem {
    
    var myTabbarViewController: UIViewController {
        
        switch self {
        case .search:
            let redViewController = UIViewController(nibName: nil, bundle: nil)
            redViewController.view.backgroundColor = UIColor.red
            return UINavigationController(rootViewController: redViewController)
        case .favorite:
            let blueViewController = UIViewController(nibName: nil, bundle: nil)
            blueViewController.view.backgroundColor = UIColor.blue
            return UINavigationController(rootViewController: blueViewController)
        }
        
    }
    
    var myTabbarItem: UITabBarItem {
        
        switch self {
        case .search:
            return UITabBarItem(tabBarSystemItem: .search, tag: 0)
        case .favorite:
            return UITabBarItem(tabBarSystemItem: .favorites, tag: 1)
        }
        
    }
    
}

TabBarController.swift

有了上面的 TabBarViewModel,TabBarController 中只需要传入包含 TabBarViewModel.TabBarItem 的一个数组进行组装并初始化即可。

// MyTabBarController.swift

import UIKit

class MyTabBarController: UITabBarController {
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    /// Initiator with an array of MyTabbarItem
    ///
    /// - Parameter items: [MyTabbarViewModel.MyTabbarItem]
    init(items: [MyTabbarViewModel.MyTabbarItem]) {
        super.init(nibName: nil, bundle: nil)
        assembleViewControllers(with: items)
    }

}

extension MyTabBarController {
    
    /// assemble ViewControllers with items
    ///
    /// - Parameter items: [MyTabbarViewModel.MyTabbarItem]
    fileprivate func assembleViewControllers(with items: [MyTabbarViewModel.MyTabbarItem]) {
        
        guard viewControllers?.count != items.count else { return }
        
        viewControllers = items.map({ (item) -> UIViewController in
            makeViewController(from: item)
        })
        
    }
    
    /// make ViewController from item
    ///
    /// - Parameter item: MyTabbarViewModel.MyTabbarItem
    /// - Returns: return a UIViewController
    fileprivate func makeViewController(from item: MyTabbarViewModel.MyTabbarItem) -> UIViewController {
        
        let controller = item.myTabbarViewController
        controller.tabBarItem = item.myTabbarItem
        
        return controller
        
    }
    
}

AppDelegate.swift

// AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = MyTabBarController(items: [.search, .favorite])
        self.window?.makeKeyAndVisible()
        
        return true
        
    }

总结

个人人为这种 TabBarController 写法分工更加明确,也更易于扩展,搭配 MVVM 设计模式下的其他模块来使用,能使得逻辑更加清晰易维护。

示例工程:thisisluke/MakeTabBarController