依然是女神鎮樓
閑話不多說,先看效果
MJTabbar-Swift.gif
自學Swift3.0中,看到了一種新方式來自定義Tabbar,覺得很有必要研究一下,記錄下來,以備后來使用和參考。
主題詞:反射機制
Java語言中是這樣定義的:反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱為java語言的反射機制。
蘋果開發語言中,系統Foundation框架為我們提供了一些方法反射的API,我們可以通過這些API執行將字符串轉為類等操作。由于OC語言的動態性,這些操作都是發生在運行時的。
NSClassFromString
NSSelectorFromString
NSProtocolFromString
通過這些方法,我們可以在運行時選擇創建那個實例,并動態選擇調用哪個方法。這些操作甚至可以由服務器傳回來的參數來控制,我們可以將服務器傳回來的類名和方法名,實例為我們的對象。
//OC方法
Class class = NSClassFromString(@"ViewController");
ViewController *vc = [[class alloc] init];
SEL selector =NSSelectorFromString(@"getDataList");
[vc performSelector:selector];
**常用判斷方法 **
// 當前對象是否這個類或其子類的實例
- (BOOL)isKindOfClass:(Class)aClass;
// 當前對象是否是這個類的實例
- (BOOL)isMemberOfClass:(Class)aClass;
// 當前對象是否遵守這個協議
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
// 當前對象是否實現這個方法
- (BOOL)respondsToSelector:(SEL)aSelector;
代碼區
- 設置子視圖控制器
func setUpChildController() {
//[clsName ,title ,imageName]
let array = [
["clsName":"MJHomeViewController","title":"首頁","imageName":"home"],
["clsName":"MJMessageViewController","title":"消息","imageName":"message_center"],
["clsName":"UIViewcontroller"],
["clsName":"MJDisCoverViewController","title":"發現","imageName":"discover"],
["clsName":"MJPrefileViewController","title":"我","imageName":"profile"],
]
var arrM = [UIViewController]()
for dict in array {
arrM.append(controller(dict: dict))
}
viewControllers = arrM
}
/// 使用字典創建控制器 反射
/// - parameter dict:信息字典[clsName ,title ,imageName]
/// - returns : 子控制器
private func controller(dict:[String:String]) -> UIViewController {
guard let clsName = dict["clsName"],
let title = dict["title"],
let imageName = dict["imageName"],
let cls = NSClassFromString(Bundle.main.namespace + "." + clsName) as? UIViewController.Type
else {
return UIViewController()
}
let vc = cls.init()
vc.title = title
//設置圖像
vc.tabBarItem.image = UIImage(named: "tabbar_" + imageName)
vc.tabBarItem.selectedImage = UIImage(named:"tabbar_" + imageName + "_selected" )?.withRenderingMode(.alwaysOriginal)
//設置字體顏色(大小)
vc.tabBarItem.setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.orange], for: .highlighted)
vc.tabBarItem.setTitleTextAttributes([NSFontAttributeName:UIFont.systemFont(ofSize: 13)], for: UIControlState(rawValue: 0)) //默認為 :12
let nav = MJNavigationController(rootViewController: vc)
return nav
}
Bundle 分類:添加一個計算屬性作為“命名空間”, 默認 “項目名稱”(最好不要有數字和特殊符號)
計算型屬性:類似于函數,沒有參數,有返回值
var namespace: String {
return infoDictionary?["CFBundleName"] as? String ?? ""
}
- 設置中間撰寫按鈕
func setUpcomposeButton() {
tabBar.addSubview(composeBtn)
let count = CGFloat(childViewControllers.count)
//將向內縮進的寬度減小,能夠讓按鈕的寬度變大,蓋住容錯點
let w = tabBar.bounds.width / count - 1
//CGRectInset 整數向內縮進,負數向外擴展
composeBtn.frame = tabBar.bounds.insetBy(dx: 2 * w, dy: 0)
composeBtn.addTarget(self, action:#selector(composeStatus), for: .touchUpInside)
}
好了,激動人心的時刻到了,奉上【demo】源代碼,你就可以愉快的使用了。拿去,不謝,內有其它福利哦。若喜歡,請點贊。
老司機,帶帶我~~~~~~