1、根据数据请求返回的数据,控制tabBar的item动态显示与隐藏:
HomeViewController.swift
private func getShowHiddenCeShi1() {
let urlString = PostPath.isDisplayTest.path
XZNetworkManager().requestWith(URLString: urlString, parameters: nil, headers: nil) { (json, isSuccess)in
if isSuccess {
if 显示 {
if data["is_display"].stringValue == "2"{
// 显示 ‘测试’ 模块
XZConst.saveSingleKey("1",key: isOpenCeShi)
}else{
// 隐藏 ‘测试’ 模块
XZConst.saveSingleKey("0",key: isOpenCeShi)
}
// 实时设置tabBarController
let mainTabBar = UIApplication.shared.keyWindow?.rootViewController as? MainViewController
mainTabBar?.setUpChildViewControllerAgain()
}
}
}
}
class MainViewController: UITabBarController {
/// 重新设置子控制器
func setUpChildViewControllerAgain2() {
guard var childrenArr = self.viewControllers else { return }
// guard var childrenArr = self.children else { return }
// 获取本地存储的字段
if let isOpen:String = XZConst.getSingleKey(isOpenCeShi) {
if isOpen == "1"{ // 显示 ‘测试’ 模块 - XZMyTestController
let test = ["clsName":"XZMyTestController","title":"测试","imgName":"rongxin"]
var hasTestModel = false
childrenArr.forEach { (navigationVc) in
if let topNavigation = navigationVc as? NavigationController, let topViewController = topNavigation.topViewController {
if topViewController.isKind(of: XZMyTestController r.self) {
hasTestModel = true
}
}
}
if !hasTestModel {
let testCon = controller(dict: test)
childrenArr.insert(testCon, at: childrenArr.count-1)
self.viewControllers?.removeAll() // 非常重要
self.setViewControllers(childrenArr, animated: true)
print("--------------添加‘测试’成功!", self.children, "\n", self.viewControllers)
}
}else { // 不显示
var hasTestModel = false
childrenArr.forEach { (navigationVc) in
let rootVc = navigationVc.children
rootVc.forEach { (childVc) in
if childVc.isKind(of: XZMyTestController.self) {
hasTestModel = true
}
}
}
if hasTestModel {
childrenArr.enumerated().forEach({ (offset: Int, element: UIViewController) in
let rootVc = element.children
rootVc.forEach { (childVc) in
if childVc.isKind(of: XZMyTestController.self) {
childrenArr.remove(at: offset)
self.viewControllers?.removeAll() // 非常重要
self.setViewControllers(childrenArr, animated: true)
print("--------------删除‘测试’成功!", self.children, "\n", self)
}
}
})
}
}
}
}
/// 使用字典创建一个子控制器
///
/// - Parameter dict: [clsName,clsName,imgName]
/// - Returns: 子控制器
private func controller(dict:[String:String]) -> UIViewController {
// 1.取得字典的值
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()
}
var vc: UIViewController
if dict["clsName"] == "XZMyIndexViewController" {
let storyboard = UIStoryboard.init(name: "XZUserAccount", bundle: nil)
vc = storyboard.instantiateViewController(withIdentifier: "XZMyIndexViewController") as! XZMyIndexViewController
}else {
// 2.创建视图控制器
vc = cls.init()
}
// 3.给子控制器设置值
vc.title = title
let image = UIImage.init(named: "tabbar_" + imgName)
vc.tabBarItem.image = image
let imageSelected = UIImage.init(named: "tabbar_" + imgName + "_selected")?.xz_originalRender
vc.tabBarItem.selectedImage = imageSelected
let nav = NavigationController.init(rootViewController: vc)
// 4.设置 tabbar 的标题字体(大小)
vc.tabBarItem.setTitleTextAttributes(
[NSAttributedString.Key.foregroundColor: UIColor.appMainColor], for: .selected)
// 系统默认是 12 号字,修改字体大小,要设置 Normal 的字体大小
vc.tabBarItem.setTitleTextAttributes(
[NSAttributedString.Key.font: Fonts_13.content],for: .normal)
return nav
}
}
需要注意的问题是:
1>给tabBarController重置子控制器的时候,需要调用的方法是setViewControllers
2>获取子控制器的方法使用viewControllers而不是children,如果tabBar的子控制器的数量大于5个,使用children获取出来的只是当前展示出来的5个,最后一个是UIMoreListController类型的,而使用viewControllers获取到的则是设置的子控制器。
3>setViewController调用之前,一定要先调用removeAll方法,去掉原来的控制器再重新设置,否则在获取新加的"测试"模块,以后该模块后面的模块的layer的位置会有问题。同理,设置timer、animation、viewControllers等等之前,也要先remove掉或销毁之前的,再设置新的;
2、如何获取UIMoreNavigationController和UIMoreListController的子控制器
之前使用children获取子控制器,获取到的子控制器是UIMoreNavigationController类型的,而该类型是苹果的私有属性,并没有公开出来,导致无法判断tabBar上是否存在"测试"模块的控制器。
下图是在MainViewController中获取viewControllers和children的打印图片: