代码创建子控制器

AppDelegate.swift

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        UITabBar.appearance().tintColor = UIColor.orange

        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = ZFTabBarController()
        window?.makeKeyAndVisible()

        return true
    }
}

ZFTabBarController.swift

第一种方式,直接重载一个addChildViewController方法,扩充一些想传的属性

import UIKit

class ZFTabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        addChildViewController(childController: UITableViewController(), tabItemTitle: "首页", tabItemImage: "tabbar_home", tabBarSelectedImage: "tabbar_home_highlighted")
        addChildViewController(childController: UITableViewController(), tabItemTitle: "消息", tabItemImage: "tabbar_discover", tabBarSelectedImage: "tabbar_discover_highlighted")
        addChildViewController(childController: UITableViewController(), tabItemTitle: "发现", tabItemImage: "tabbar_compose_icon_add", tabBarSelectedImage: "tabbar_compose_icon_add_highlighted")
        addChildViewController(childController: UITableViewController(), tabItemTitle: "我", tabItemImage: "tabbar_profile", tabBarSelectedImage: "tabbar_profile_highlighted")

    }

    func addChildViewController(childController: UIViewController,tabItemTitle:String,tabItemImage:String,tabBarSelectedImage:String) {
        self.addChildViewController(childController)

        childController.title = tabItemTitle
        childController.tabBarItem.image = UIImage(named: tabItemImage)
        childController.tabBarItem.selectedImage = UIImage(named: tabBarSelectedImage)
    }    
}

第二种方式,通过类名字符串创建控制器

import UIKit

class ZFTabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        addChildViewController(childControllerClass: "ZFHomeViewController", tabItemTitle: "首页", tabItemImage: "tabbar_home", tabBarSelectedImage: "tabbar_home_highlighted")
        addChildViewController(childControllerClass: "ZFMsgViewController", tabItemTitle: "消息", tabItemImage: "tabbar_discover", tabBarSelectedImage: "tabbar_discover_highlighted")
        addChildViewController(childControllerClass: "ZFDiscoverViewController", tabItemTitle: "发现", tabItemImage: "tabbar_compose_icon_add", tabBarSelectedImage: "tabbar_compose_icon_add_highlighted")
        addChildViewController(childControllerClass: "ZFProfileViewController", tabItemTitle: "我", tabItemImage: "tabbar_profile", tabBarSelectedImage: "tabbar_profile_highlighted")
    }

    func addChildViewController(childControllerClass: String,tabItemTitle:String,tabItemImage:String,tabBarSelectedImage:String) {
        //swift要保证每一个对象的值都要严格的类型匹配,所以一定要使用可选类型先尝试创建,然后判断对象是否为nil后再做后面的工作

        //自定义的类要先获取命名空间,而不能直接使用类名的字符串
        //CFBundleExecutable字段在哪里看?info.plist -> Executable file
        guard let namespace = Bundle.main.infoDictionary?["CFBundleExecutable"] as? String else
        {
            print("命名空间获取失败")

            return
        }

        //确保命名空间获取到以后,将命名空间和类名字符串通过 命名空间 + "." + 类名字符串 的格式拼接
        guard let childClassStr = NSClassFromString(namespace + "." + childControllerClass) else {

            print("找不到Class\(childControllerClass)")

            return
        }

        //确保前面获取到的完整类标识属于UIViewController类型
        guard let childVCType = childClassStr as? UIViewController.Type else {

            print("没有获取到对应的控制器类型")

            return
        }

        //经过如上的过滤,确保这个类字符串真的是一个UIViewController的类型,才能做对控制器的一些属性设置等常规操作
        let childVC = childVCType.init()
        childVC.title = tabItemTitle
        childVC.tabBarItem.image = UIImage(named: tabItemImage)
        childVC.tabBarItem.selectedImage = UIImage(named: tabBarSelectedImage)

        self.addChildViewController(childVC)
    }
}

第三种,读取一个json文件来通过字符串创建子控制器

假如json如下:

[
 {
    "vcName": "ZFHomeViewController",
    "title": "首页",
    "imageName": "tabbar_home"
 },
 {
     "vcName": "ZFMsgViewController",
     "title": "消息",
     "imageName": "tabbar_message_center"
 },
 {
     "vcName": "ZFDiscoverViewController",
     "title": "发现",
     "imageName": "tabbar_discover"
 },
 {
     "vcName": "ZFProfileViewController",
     "title": "我",
     "imageName": "tabbar_profile"
 }
]
import UIKit

class ZFTabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        //先读取json
        guard let jsonPath = Bundle.main.path(forResource: "MainVCSettings.json", ofType: nil) else {
            print("json文件不存在")

            return
        }

        //如果json文件读取成功,再看看能不能转换成二进制数据
        guard let jsonData = NSData.init(contentsOfFile: jsonPath) else {

            print("数据错误")

            return
        }

        //如果二进制数据转换成功,尝试解析json
        guard let tempObject = try? JSONSerialization.jsonObject(with: jsonData as Data, options: .mutableContainers) else {

            return
        }

        //json解析成功,再来尝试能不能把json转换成字典数组,[[String : Any]]表示字典数组
        guard let dictArray = tempObject as? [[String : Any]] else {
            return
        }

        //以上过滤都通过,就可以放心的使用稳定的json转换为的字典数组中的数据了
        for dict in dictArray
        {
            guard let vcName = dict["vcName"] as? String else {
                continue
            }

            guard let title = dict["title"] as? String else {
                continue
            }

            guard let imageName = dict["imageName"] as? String else {
                continue
            }

            //按照方式二创建各个子控制器
            addChildViewController(childControllerClass: vcName, tabItemTitle: title, tabItemImage: imageName, tabBarSelectedImage: imageName + "_highlighted")
        }
    }

    func addChildViewController(childControllerClass: String,tabItemTitle:String,tabItemImage:String,tabBarSelectedImage:String) {

        //info.plist -> Executable file
        guard let namespace = Bundle.main.infoDictionary?["CFBundleExecutable"] as? String else
        {
            print("命名空间获取失败")

            return
        }

        guard let childClassStr = NSClassFromString(namespace + "." + childControllerClass) else {

            print("找不到Class\(childControllerClass)")

            return
        }

        guard let childVCType = childClassStr as? UIViewController.Type else {

            print("没有获取到对应的控制器类型")

            return
        }

        let childVC = childVCType.init()
        childVC.title = tabItemTitle
        childVC.tabBarItem.image = UIImage(named: tabItemImage)
        childVC.tabBarItem.selectedImage = UIImage(named: tabBarSelectedImage)

        self.addChildViewController(childVC)
    }
}

results matching ""

    No results matching ""