不可不知的自定義Tabbar新方式

依然是女神鎮樓

閑話不多說,先看效果


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】源代碼,你就可以愉快的使用了。拿去,不謝,內有其它福利哦。若喜歡,請點贊。
老司機,帶帶我~~~~~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容