Swift微博項目--Swift中通過類名字符串創建類以及動態加載控制器的實現


Swift中用類名字符串創建類(用到了命名空間)

  • OC中可以直接通過類名的字符串轉換成對應的類來操作,但是Swift中必須用到命名空間,也就是說Swift中通過字符串獲取類的方式為NSClassFromString(命名空間.類名)

        // 1.獲取命名空間
        // 通過字典的鍵來取值,如果鍵名不存在,那么取出來的值有可能就為沒值.所以通過字典取出的值的類型為AnyObject?
        guard let clsName = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] else {
            ChaosLog("命名空間不存在")
            return
        }
        // 2.通過命名空間和類名轉換成類
        let cls : AnyClass? = NSClassFromString((clsName as! String) + "." + childControllerName)
  • 得到了類名之后還不算完,Swift中通過class創建一個對象,必須告訴系統class的類型type

        // swift 中通過Class創建一個對象,必須告訴系統Class的類型
        guard let clsType = cls as? UITableViewController.Type else {
            ChaosLog("無法轉換成UITableViewController")
            return
        }

        // 3.通過得到的class類型創建對象
        let childController = clsType.init()
  • 項目中的代碼

  • 外界調用的代碼
self .addChildViewController("HomeTableViewController", title: "首頁", normalImage: "tabbar_home")
  • 方法的實現代碼
private func addChildViewController(childControllerName : String,title : String,normalImage : String) {

        // 1.獲取命名空間
        guard let clsName = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] else {
            ChaosLog("命名空間不存在")
            return
        }
        // 2.通過命名空間和類名轉換成類
        let cls : AnyClass? = NSClassFromString((clsName as! String) + "." + childControllerName)

        // swift 中通過Class創建一個對象,必須告訴系統Class的類型
        guard let clsType = cls as? UITableViewController.Type else {
            ChaosLog("無法轉換成UITableViewController")
            return
        }

        // 3.通過Class創建對象
        let childController = clsType.init()

        // 設置TabBar和Nav的標題
        childController.title = title
        childController.tabBarItem.image = UIImage(named: normalImage)
        childController.tabBarItem.selectedImage = UIImage(named: normalImage + "_highlighted")

        // 包裝導航控制器
        let nav = UINavigationController(rootViewController: childController)
        self.addChildViewController(nav)
    }

動態加載控制器的實現

  • 應用場景:搞活動的時候,TabBarVC的子控制器有的會改變,例如過年的時候'我'控制器改成了'搶紅包'控制器.

  • 實現思路:程序發布的時候,所有控制器已經做好.每次進入程序,根據服務器響應的數據來控制哪些控制器需要顯示.案例中用json數據模擬服務器的動態數據

    private func addChildren() ->Void {

        // 模擬動態加載,根據服務器返回的數據加載對應的控制器 -- 這里直接用的json文件

        // 1.加載json數據
        guard let path = NSBundle.mainBundle().pathForResource("MainVCSettings", ofType: "json") else {
            ChaosLog("json文件不存在")
            return
        }

        guard let data = NSData(contentsOfFile: path) else {
            ChaosLog("加載二進制數據失敗")
            return
        }

        /*
         OC中的異常處理:傳入一個error指針,將錯誤賦值給error指針
         swift的異常處理: 有throw的方法,就要try catch 起來 do{}catch{do中出現錯誤異常才執行這里的代碼}
         swift中異常處理的三種方式:
         try : 正常處理,必須用到do {} catch {}
         try! : 告訴系統一定沒有異常,也就是說不用do catch來處理,開發中不建議用.一旦有異常,程序崩潰
         try? : 告訴系統可能有異常,也可能沒有異常.如果沒有異常,系統會自動將結果包裝成一個可選類型給你,如果有異常,系統會返回nil.如果使用try?可以不是同do catch進行處理
        */
        // 2.解析json,得到字典數組
        do {
            let objc = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments) as! [[String : AnyObject]]

            // 3.遍歷字典數組,創建子控制器
            for dict in objc {

                guard let title = dict["title"] as? String else {
                    return
                }
                guard let vcName = dict["vcName"] as? String else {
                    return
                }
                guard let imageName = dict["imageName"] as? String else {
                    return
                }

                addChildViewController(vcName, title: title, normalImage: imageName)
            }

        } catch {
            // json數據異常,以默認方式創建控制器

            self .addChildViewController("HomeTableViewController", title: "首頁", normalImage: "tabbar_home")
            self .addChildViewController("MessageTableViewController", title: "消息", normalImage: "tabbar_message_center")
            self .addChildViewController("NullViewController", title: "", normalImage: "")
            self .addChildViewController("DiscoverTableViewController", title: "發現", normalImage: "tabbar_discover")
            self .addChildViewController("ProfileTableViewController", title: "我", normalImage: "tabbar_profile")

        }

        // 設置的渲染顏色,不影響非選中狀態的顏色
        self.tabBar.tintColor = UIColor.orangeColor()
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM