
閑話不多說,先看效果

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