swift 自定义tabbar为基本结构的项目
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>