• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

iOS(Swift)-Runtime之关于页面跳转的捷径【Runtime获取当前ViewController,很常用】 ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

写在前面

在我们操作页面跳转时,如果当前的类不是UIViewcontroller(下面用VC表示),你会不会写一个代理,或者block给VC传递信息,然后在VC里面进行

 ///假如targetVc是将要跳转的页面
 [self.navigationController pushViewController:targetVc animated:YES];

拿tableViewCell做例子,如果每个页面展示的tableViewCell中,如果存在不少的这样操作,就会写很多代理或者block,如果不这样,那又该怎么做呢,思路是获取当前显示在最顶层的VC,网上有很多方法,先看一个普通的方法

- (UIViewController *)currentViewController {
    UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
    UIViewController *vc = keyWindow.rootViewController;
    while (vc.presentedViewController) {
        vc = vc.presentedViewController;
        
        if ([vc isKindOfClass:[UINavigationController class]]) {
            vc = [(UINavigationController *)vc visibleViewController];
        } else if ([vc isKindOfClass:[UITabBarController class]]) {
            vc = [(UITabBarController *)vc selectedViewController];
        }
    }
    return vc;
}

上面的方法可以或许可以获取最顶层的VC(我在网上找的一个,没有测试,这里只做对比),但是有没有感觉很繁琐,当然也可以把它写在一个工具里面,每次用这个工具里面的这个方法,也可以获取,但是我始终觉得繁琐,哈哈;

利用Runtime实现

runtime是一个好玩的东西,上一篇我简单说了它的一些常用功能,这里结合Category来实现获取当前VC需求

1.新建一个基于UIApplication的分类

 

点击下一步就建好了

2.利用Runtime添加属性

在UIApplication+CurrentViewController.h文件中,添加

///用于获取当前 UIViewController
@property (nonatomic, weak) UIViewController *currentViewController;

在UIApplication+CurrentViewController.m文件中,引入头文件

#import <objc/runtime.h>

利用runtime实现属性的get set方法

///set
- (void)setCurrentViewController:(UIViewController *)currentViewController{
    objc_setAssociatedObject(self, @selector(currentViewController), currentViewController, OBJC_ASSOCIATION_ASSIGN);
}
///get
- (UIViewController *)currentViewController{
    return objc_getAssociatedObject(self, _cmd);
}

3.实现

在需要获取当前VC的文件中,引入头文件,也可以直接将该头文件放入宏文件中

#import "UIApplication+CurrentViewController.h"

在VC的viewWillAppear方法中,添加

[UIApplication sharedApplication].currentViewController = self;

这样,我们在任何一个地方获取,只需要添加如下代码,就可以获取当前的VC,获取到之后,不管是push、present还是performSegueWithIdentifier,都可以实现页面的跳转

UIViewController *viewVc = [UIApplication sharedApplication].currentViewController;

4.延伸

上面在需要用到的在每一个VC中都需要添加

[UIApplication sharedApplication].currentViewController = self;

那么,可以建一个基于UIViewController的基类BaseViewController,然后在BaseViewController的viewWillAppear方法中添加上述代码,我们在新建VC时,只需要继承BaseViewController就可以了!

 

*****************Swift实现*****************

extension UIApplication {
    struct RuntimecurrVcKey {
        static let currVcKey = UnsafeRawPointer.init(bitPattern: "currVcKey".hashValue)
    }

    var currViewController: UIViewController? {
        get {
            return  objc_getAssociatedObject(self, UIApplication.RuntimecurrVcKey.currVcKey!) as? UIViewController
        }
        set(newValue) {
            objc_setAssociatedObject(self, UIApplication.RuntimecurrVcKey.currVcKey!, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
        }
    }
}

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Swift3.0语言教程删除字符与处理字符编码发布时间:2022-07-13
下一篇:
号称将推动应用开发巨变的 Swift 语言是什么?发布时间:2022-07-13
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap