iOS开发过程中,我们会遇到控制器跳转的问题。
几种情况:
- 1.推送:根据服务器推送过来的信息,跳转不同控制器;
- 2.首页轮播图:首页轮播图一般展示的信息都是各模块的精彩信息,跳转控制器一般都会有几种;
- 3.还有一些奇葩的需求吧(哈哈),比如一个列表cell跳转不同控制器;
这些需求,我们可以在移动端使用if else或者switch判断不同类型,实现跳转,但是想一想,是不是特别麻烦,肯定都有拿板砖的冲动了!
思考一下:是不是可以通过下面的方法解决呢,方便灵活!请看代码:
-
WMJumpControllerTool.h
#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface WMJumpControllerTool : NSObject /** 控制器跳转的方法 params:跳转所需要的信息,这个需要和服务器端沟通好,包含信息:需要跳转的控制器名,跳转需要的字段以及其他可能的信息。 */ + (void)jumpViewControllerWithParams:(NSDictionary *)params; @end NS_ASSUME_NONNULL_END
-
WMJumpControllerTool.m
#import "WMJumpControllerTool.h" #import <UIKit/UIKit.h> #import <objc/runtime.h> @implementation WMJumpControllerTool /** params此处的格式为: @{ @"class":@"跳转目标类名", @"property":@{ @"name":@"字段" }, }; 此为服务器返回数据,包含目标控制器字段:目标控制器名,属性名和属性值 我们需在目标控制器.h文件中声明对应的属性名的属性。 */ + (void)jumpViewControllerWithParams:(NSDictionary *)params { ///获取控制器类名字符串 NSString *classNameStr = [NSString stringWithFormat:@"%@", params[@"class"]]; const char *className = [classNameStr cStringUsingEncoding:NSASCIIStringEncoding]; // 根据字符串返回一个类 Class newClass = objc_getClass(className); if (!newClass) { // 创建一个类 Class superClass = [NSObject class]; newClass = objc_allocateClassPair(superClass, className, 0); // 注册你创建的这个类 objc_registerClassPair(newClass); } // 创建对象(目标控制器对象) id instance = [[newClass alloc] init]; NSDictionary *propertys = params[@"property"]; [propertys enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { // 检测这个对象是否存在该属性 if ([WMJumpControllerTool checkIsExistPropertyWithInstance:instance verifyPropertyName:key]) { // 利用 KVC 对控制器对象的属性赋值 [instance setValue:obj forKey:key]; } }]; // 跳转到对应的控制器 [[WMJumpControllerTool topViewController].navigationController pushViewController:instance animated:YES]; } // 检测对象是否存在该属性 + (BOOL)checkIsExistPropertyWithInstance:(id)instance verifyPropertyName:(NSString *)verifyPropertyName { unsigned int count, i; // 获取对象里的属性列表 objc_property_t *properties = class_copyPropertyList([instance class], &count); for (i = 0; i < count; i++) { objc_property_t property =properties[i]; // 属性名转成字符串 NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding]; // 判断该属性是否存在 if ([propertyName isEqualToString:verifyPropertyName]) { free(properties); return YES; } } free(properties); return NO; } // 获取当前显示在屏幕最顶层的 ViewController + (UIViewController *)topViewController { UIViewController *resultVC = [WMJumpControllerTool _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]]; while (resultVC.presentedViewController) { resultVC = [WMJumpControllerTool _topViewController:resultVC.presentedViewController]; } return resultVC; } + (UIViewController *)_topViewController:(UIViewController *)vc { if ([vc isKindOfClass:[UINavigationController class]]) { return [WMJumpControllerTool _topViewController:[(UINavigationController *)vc topViewController]]; } else if ([vc isKindOfClass:[UITabBarController class]]) { return [WMJumpControllerTool _topViewController:[(UITabBarController *)vc selectedViewController]]; } else { return vc; } return nil; } @end
举例:
NSDictionary *dict = @{
@"class":@"WMJumpController",
@"property":@{
@"name":@"Hello World!"
},
};
[WMJumpControllerTool jumpViewControllerWithParams:dict];
好啦,实现了!