zoukankan      html  css  js  c++  java
  • 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()
        }
    
  • 相关阅读:
    poj 2187 Beauty Contest(旋转卡壳)
    poj 2540 Hotter Colder(极角计算半平面交)
    poj 1279 Art Gallery(利用极角计算半平面交)
    poj 3384 Feng Shui(半平面交的联机算法)
    poj 1151 Atlantis(矩形面积并)
    zoj 1659 Mobile Phone Coverage(矩形面积并)
    uva 10213 How Many Pieces of Land (欧拉公式计算多面体)
    uva 190 Circle Through Three Points(三点求外心)
    zoj 1280 Intersecting Lines(两直线交点)
    poj 1041 John's trip(欧拉回路)
  • 原文地址:https://www.cnblogs.com/gchlcc/p/5621930.html
Copyright © 2011-2022 走看看