美文网首页
如何更好的跳转,更便利的Self-Manager

如何更好的跳转,更便利的Self-Manager

作者: lsdoy | 来源:发表于2015-12-29 11:32 被阅读0次

    我们在开发过程中总会遇到如下场景:

    1.tableviewcell(view)中的控件点击需要跳转到各种页面

    2.在使用app或者开打app,需要处理远程通知的跳转

    跳转总是需要CurrentViewController

    在app中做跳转,我们总是需要获得一个可以ViewController来做转场动画,通常的场景就是正在展示的ViewController做push或者present,特别是在Self-Manager这种思想下,因为控件的self-manager之后需要handle事件,比如跳转

    @implementation FDAvatarView (FDAvatarViewSelfManager)
    // 为后一个页面的创建增加了个 UID 参数
    - (void)selfManagedConfigureWithAvatarURL:(NSURL *)URL VIPInfo:(id)info UID:(NSString *)UID {
        [self configureWithAvatarURL:URL VIPInfo:info tapped:^{
            // 假设 App 结构是 Root -> TabBar -> Navigation -> ViewController
            UITabBarController *tabBarControler = (id)[UIApplication.sharedApplication.delegate.window.rootViewController;
            UINavigationController *navigationController = tabBarControler.selectedViewController;
            // 创建用户信息 View Controller
            FDUserProfileViewController *profileViewController = [FDUserProfileViewController viewControllerWithUID:UID];
            [navigationController pushViewController:profileViewController animated:YES];
        }];
    }
    @end
    

    然而控件可能会出现在各种各样的ViewController中,如何获得当前的ViewController

    获得CurrentViewController

    demo地址:https://github.com/Sdoy/CurrentViewController

    写一个继承自UIViewController的子类,就叫BaseViewController

    @interface BaseViewController : UIViewController
    
    @end
    

    然后在BaseViewController中将self绑定到Application中的currentViewController属性

    @implementation BaseViewController
    
    -(void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        [UIApplication sharedApplication].currentViewController=self;
    }
    @end
    

    恩,如何绑定?
    为UIApplication写一个Category

    @interface UIApplication (CurrentViewController)
    
    @property (nonatomic, weak) UIViewController *currentViewController;
    
    @end
    

    .m文件

    #import "UIApplication+CurrentViewController.h"
    #import <objc/runtime.h>
    @implementation UIApplication (CurrentViewController)
    -(void)setCurrentViewController:(UIViewController *)currentViewController
    {
        objc_setAssociatedObject(self, @selector(currentViewController), currentViewController, OBJC_ASSOCIATION_ASSIGN);
    }
    -(UIViewController *)currentViewController
    {
        return objc_getAssociatedObject(self, _cmd);
    }
    @end
    

    至此,只要你的ViewController都是继承自BaseViewController,你就可以在任何地方都能拿到CurrentViewController了,调用起来是这样的

    比如收到了远程通知:

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
        
        //You can esay find out which view controller is on the screen here.
        UIViewController *currentVC=[UIApplication sharedApplication].currentViewController;
       NSLog(@"%@",currentVC);
    }
    

    或者在子控件做跳转:

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        //if you want to go another view controller when you touch this view
        //you don't need create a delegate to let the display or some view controller to perform SEL
         NSLog(@"%@",[UIApplication sharedApplication].currentViewController);
        
        AnotherViewController *another=[[AnotherViewController alloc]init];
        [[UIApplication sharedApplication].currentViewController.navigationController pushViewController:another animated:YES];
    
    }
    

    而且还写了3个宏定义,用起来更方便

    #define CurrentVC [UIApplication sharedApplication].currentViewController
    
    #define PushVC(ViewController) [[UIApplication sharedApplication].currentViewController.navigationController pushViewController:ViewController animated:YES]
    
    #define PresentVC(ViewController)\
    UINavigationController *nv=[[UINavigationController alloc]initWithRootViewController:ViewController];\
    [[UIApplication sharedApplication].currentViewController presentViewController:nv animated:YES completion:nil]
    

    为什么不直接hook,UIViewController的viewWillAppear:方法?

    因为很多苹果的私有组件都是继承自UIViewController的,他们也许是没有nav的

    如果在一些特殊情况下,没有经过ViewWillAppear方法

    可以用[UIApplication topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController]方法来获取

    相关文章

      网友评论

          本文标题:如何更好的跳转,更便利的Self-Manager

          本文链接:https://www.haomeiwen.com/subject/togbhttx.html