iOS推送从任意页面跳转任意页面

其实这篇文章,是上篇文章Runtime的应用部分的展开,从任意页面跳转任意页面这块主要不是Runtime的知识点,所以没在上篇文章中进行展开。
首先新建一个工程,并在storyboard上面拖出来一个UITabBarController,加上两个UINavgationController,再加上四个UIViewController,具体布局如图:


storyboard布局.png

然后再建四个UIViewController子类,并绑定到Storyboard上面的ViewController上面,并设置Storyboard ID


新建VC子类.png

然后storyboard的每个ViewController上面添加两个Label,并绑定到代码文件里面。然后给暖色One和暗色One的View添加点击一个手势,把点击事件绑定到代码文件里面,我的属性事件命名就随意了。
绑定.png

然后在手势点击事件方法,写上跳转到Two页面的代码。
下面我们新建五个DataModel,一个PushModel,四个相应的VC的DataModel,我就取名WarmOneDataModel ,WarmTwoDataModel , DeadOneDataModel,DeadTwoDataModel(命名随意)

Model.png

然后在PushModel里面写上四个属性,类型则是另外四个Model

PushModel.png

四个VC的Model里面的代码是一样的(主要是省事,实际项目里面肯定不是这样的了)


dataModel.png

然后在几个对应的ViewController写上对应的DataModel类型的属性,再把topLabelStr和BottomLabelStr取出来赋值给两个Lable。

赋值.png

目前前期准备工作已经完成了,下面需要在AppDelegate里面开始处理推送过来的信息,已经跳转,传值逻辑了。
我新建了一个SwiftRunTimeTool 类

class func checkClassPerporty(object : AnyClass , propertyStr: String) -> Bool{
        var count : UInt32 = 0
        let propertys = class_copyPropertyList(object, &count)
        for index in 0 ..< Int(count){
            let name = property_getName(propertys?[index])
            if let propertyName = String.init(validatingUTF8: name!){
                if propertyName == propertyStr{
                    return true
                }
            }
        }
        return false
    }

利用Runtime做KVC之前的保护
关于push过来的信息格式,需要和后台进行对接好,不然错误的key,name,会导致取不到想要的值

 // let params = ["class" : "填入需要跳转VC名字字符串" , "property" : [ "跳入VC需要用到的数据Model":["数据Model属性字符串" : "数据Model属性值"] ] , "modelName" : "数据Model在pushModel中的名字"] as [String : Any]
 //模拟推送过来的信息
    func setPushParams() ->[String : AnyObject]{
        let params = ["class" : "WarmColorOneViewController" , "property" : [ "WarmOneDataModel":["topLabelStr" : "我是推送过来的信息" , "bottomLabelStr" : "我也是推送过来的信息"] ] , "modelName" : "warmOneModel"] as [String : Any]
        return params as [String : AnyObject]
    }

然后再写一个方法

//处理推送信息进行跳转传值方法
    func conductPushParams(params : [String : AnyObject]){
        
    }

接下来在本地新建一个plist文件,新建四个item,key是四个类的类名字符串,value是对应的Storyboard ID

Storyboard ID.png
    //处理推送信息进行跳转传值方法
    func conductPushParams(params : [String : AnyObject]){
        //先检查推送过来的字典里面Class存不存在
        guard let className = params["class"] as? String else{
            print("参数类名不存在")
            return
        }
        //读取Plist文件
        let filePath = Bundle.main.path(forResource: "VCStoryboardIDList", ofType: "plist") ?? ""
        let vcDic : NSDictionary = NSDictionary(contentsOfFile: filePath) ?? NSDictionary()
        
        //判断plist文件里面是否含有目标VC的Storyboard ID
        if let vcID = vcDic[className] {
            
            guard let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] else {
                print("命名空间不存在")
                return
            }
            //如果VC是与storyboard关联的通过下面的语句创建VC对象
            let clsVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier:  vcID as! String)
            
            setPushModelInfo(clsVC: clsVC, params: params, nameSpace: nameSpace as! String)
        }else{

            guard let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] else {
                print("命名空间不存在")
                return
            }
            //如果不是storyboard绑定的UIViewController 则通过这种方式创建其对象
            let vcClassTemp : AnyClass? = NSClassFromString((nameSpace as! String) + "." + className)
            guard let vcClsType = vcClassTemp as? UIViewController.Type else{
                print("无法转换为UIViewController类型")
                return
            }
            //创建对应View Controller 对象
            let clsVC = vcClsType.init()
            setPushModelInfo(clsVC: clsVC, params: params, nameSpace: nameSpace as! String)
        }
    }
    //因为conductPushParams里面if else里面重复代码挺多,所以我抽离出来重新写了一个方法
    func setPushModelInfo(clsVC : UIViewController , params : [String : Any] , nameSpace : String){
        
        //创建PushModel 对象
        let pushModel = PushModel()
        
        //根据 params["property"]里面的dataModel名字字符串,创建其对象,首先获取命名空间字符串
        guard let propertyDic = params["property"] as? [String : Any] else{
            print("property信息不存在")
            return
        }
        for key in propertyDic.keys{
            //然后NSClassFromString获取到DataModel 的Class
            let modelClassTemp : AnyClass? = NSClassFromString((nameSpace) + "." + key)
            //然后判断有没有获取成功
            guard let modleClsType = modelClassTemp as? NSObject.Type else{
                return
            }
            //根据推送过来的信息对dataModel进行赋值
            guard let modelDic = propertyDic[key] as? [String : String]else{
                print("model信息不存在")
                return
            }
            let dataModel = modleClsType.init()
            for modelKey in modelDic.keys{
                //首先确定model里面有相应的属性
                if SwiftRunTimeTool.checkClassPerporty(object: object_getClass(dataModel), propertyStr: modelKey){
                    dataModel.setValue(modelDic[modelKey]! as String, forKey: modelKey)
                }
            }
            //再根据推送过来dataModel再pushModel里面的名字字符串,对pushModel进行赋值
            guard let modelName = params["modelName"] as? String else{
                print("modelName不存在")
                return
            }
            //确保pushModel里面有对应名字的属性
            if SwiftRunTimeTool.checkClassPerporty(object: object_getClass(pushModel), propertyStr: modelName){
                pushModel.setValue(dataModel, forKey: modelName)
            }
        }
        //确保跳转的VC里面有pushModel属性
        if SwiftRunTimeTool.checkClassPerporty(object: object_getClass(clsVC), propertyStr: "pushModel"){
            clsVC.setValue(pushModel, forKey: "pushModel")
        }
        
        //找UITabBarController
        guard let tabBarController = self.window?.rootViewController as?UITabBarController else {
            print("UITabBarController找不到")
            return
        }
        //找UINavigationController
        guard let navigationController = tabBarController.viewControllers?[tabBarController.selectedIndex] as? UINavigationController else {
            print("navigationController找不到")
            return
        }
        //如果有Present上出的页面,可以通过 tabBarController调用Dismiss
//        tabBarController.dismiss(animated: true, completion: nil)
        
        clsVC.hidesBottomBarWhenPushed = true
        navigationController.pushViewController(clsVC, animated: true)
    }

好了,至此算是结束了,如果和后台对接好,理论上可以进行任意页面的跳转。。。最终Demo在这里:最终Demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,943评论 4 60
  • 佛讲法华八年整,一部开权显实经。弗曰读研与熏习,无量劫善见经名。 叹未生逢佛在世,叹未亲闻佛法时。泪奔祖师全不见,...
    真如自在阅读 521评论 0 3
  • 有些回忆还在脑子里存在,不知如何说起,对你的回忆占据心里一大部分,怎么说呢?从今天开始一直往前说起吧,今天是父亲节...
    轻舞listen飞洋阅读 241评论 0 0
  • 我国有数千所大学几千万在校大学生,是经商人必争的“风水宝地”,也是买卖人赚大钱、赚快钱的好地方。那么,时下在大学旁...
    创业咨询指导阅读 2,551评论 0 0