swift 自定义tabbar为基本结构的项目

发布时间 2023-04-18 18:34:38作者: wjwdive

swift 自定义tabbar
1、Xcode新建一个项目,选择布局方式为storyBoard, 语言为swift
2、打开项目,新建一个cocoa文件,继承于TabBarViewController,名字命名为BaseTabBarViewController
3、勾选main storyboard,选中右侧窗口第四个检查项,将Class 关联到BaseTabBarViewController
4、新建4个根模块的字控制器,【HomeViewController,RecomentViewController,FavoriteViewController,MyViewController】编写BaseTabBarViewController的代码

import Foundation
import UIKit

class BaseTabBarViewController : UITabBarController {
//    @IBOutlet weak var baseTabbvar: UITabBar!
    
    override func viewDidLoad() {
        super.viewDidLoad()
//        self.tabBar.tintColor = .lightGray//图片和文字都为成为该颜色,图片原来的颜色会改变
        // 创建四个子视图控制器
        let vc1 = createNavigationController(for: HomeViewController())
        let vc2 = createNavigationController(for: RecomentViewController())
        let vc3 = createNavigationController(for: FavoriteViewController())
        let vc4 = createNavigationController(for: MyViewController())
        // 分别设置子视图控制器的 tabBarItem
        vc1.tabBarItem = UITabBarItem.init(title: "首页", image: UIImage(named: "homepage_blue") ,selectedImage: UIImage(named: "homepage_fill_blue"))
        vc2.tabBarItem = UITabBarItem.init(title: "推荐", image: UIImage(named: "activity_blue"), selectedImage: UIImage(named: "activity_fill_blue"))
        vc3.tabBarItem = UITabBarItem.init(title: "喜欢", image: UIImage(named: "like_blue"), selectedImage: UIImage(named: "like_fill_blue"))
        vc4.tabBarItem = UITabBarItem.init(title: "我的", image: UIImage(named: "people_blue") ,selectedImage: UIImage(named: "people_fill_blue"))
        // 将子视图控制器添加到 tabBarController 中
        viewControllers = [vc1, vc2, vc3, vc4]
    }
    
    // 创建一个包装好的 UINavigationController,传入需要包装的控制器
    func createNavigationController(for viewController: UIViewController) -> UINavigationController {
        let navController = UINavigationController(rootViewController: viewController)
        return navController
    }
}

我们在Home页建立一个tableView,菜单里是自页面的名称。
代码如下: ["HitoryTodayViewController", "HuangLiViewController"]是子页面,我们也要新建对应的控制器

import Foundation
import UIKit

class HomeViewController : BaseViewController, UITableViewDelegate, UITableViewDataSource {
    
    var _tableView: UITableView?
    var meunItems: Array<String> = ["HitoryTodayViewController", "HuangLiViewController"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "首页"
        self.view.backgroundColor = .white
        
//        meunItems.addObject("HitoryTodayViewController")
        
        _tableView = UITableView(frame: self.view.bounds, style: .plain)
        self.view .addSubview(_tableView!)
        _tableView?.delegate = self
        _tableView?.dataSource = self
        _tableView?.frame = self.view.bounds
    }
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return meunItems.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCell(withIdentifier: "cellID")
        if(cell == nil) {
            cell = UITableViewCell(style: .default, reuseIdentifier: "cellID")
        }
        cell!.textLabel?.text = "\(indexPath.row)" + "\(meunItems[indexPath.row])"
        return cell!
    }
    
    //didSelectRowAt
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("tableView didSelectRowAt、 \(indexPath.row)")
        
        let classStr = meunItems[indexPath.row]
        // 3.通过Class创建对象
        let vc = vcClassFromString(classStr)
        
        self.navigationController?.pushViewController(vc, animated: true)
    }
    
    
    func vcClassFromString(_ className:String) -> UIViewController{
        //1、获swift中的命名空间名
        var name = Bundle.main.object(forInfoDictionaryKey: "CFBundleExecutable") as? String
        //2、如果包名中有'-'横线这样的字符,在拿到包名后,还需要把包名的'-'转换成'_'下横线
        name = name?.replacingOccurrences(of: "-", with: "_")
        //3、拼接命名空间和类名,”包名.类名“
        let fullClassName = name! + "." + className
        //通过NSClassFromString获取到最终的类,由于NSClassFromString返回的是AnyClass,这里要转换成UIViewController.Type类型
        guard let classType = NSClassFromString(fullClassName) as? UIViewController.Type  else{
            fatalError("转换失败")
        }
        return classType.init()
    }
    
    
    override func viewDidLayoutSubviews() {
        
    }
}

其中网络请求和根据字符串返回类名需要做一下Info.plist的配置:

	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>
	<key>CFBundleExecutable</key>
	<string>swiftUIKitdemo</string>