父子控制器和MJ框架底层RunTime思想(二)
来源:互联网 发布:多玩数据库魔兽3.35 编辑:程序博客网 时间:2024/06/07 12:56
一 父子控制器
控制器需要了解的知识:
1 谁modal,谁dismiss
—-> dismiss的原理:判断当前的通知其是否是modal出来的控制器,如果是那么就dismiss;判断父控制器是否是modal出来的控制器,如果是,那么就dismiss,如果不是,那么就逐级的往上找,一直判断,直到没有父控制器.
2 拿到导航控制器的条件
—–> // 只要是导航控制器的子控制器就能拿到导航控制器
—–> // 判断下当前控制器是否是导航控制器的子控制,判断下自己的父控制器是否是导航控制器的子控制器,继续寻找有没有父控制器
3 addSubView的原理:只要添加一个viewA,先判断viewA有没有父控件,如果有父控件,先将父控件移除,在重新添加到对应的view
4 一个通过运用父子控制器实现的案例
4.1 功能图:(类似于UITabBarController功能)
—–> 原理:通过运用父子控制器的原理,我们始终只保证控制器的view只有一个.同时达到了控制器的切换,还有能监听选中后控制器的点击事件.
—–> 思路:
——-> 1上面部分的类似导航条的功能部分,采用一个view作为三个按钮的父控件.
——-> 2 创建三个控制器,我们都将控制器通过addChildViewController方法加入到父控制器中
——-> 3 当点击不同的按钮的时候,我们不是将控制器加入 ,而是将控制器的view加入到父控件的view中
——-> 4 如何保证程序运行中只有一个view呢?用一个普通的view来装容器,类似于UITabBarController一样装控件的view
代码块一:设置控制器
#pragma mark - 设置子控制器- (void)setWithChildCode{ //创建控制器 XFJHotViewController *hvc = [[XFJHotViewController alloc] init]; //设置标题 hvc.title = @"热点"; //添加控制器到view中 [self addChildViewController:hvc]; //创建控制器 XFJSocietyViewController *svc = [[XFJSocietyViewController alloc] init]; svc.title = @"社会"; //添加 [self addChildViewController:svc]; //创建控制器 XFJTopLineViewController *lvc = [[XFJTopLineViewController alloc] init]; lvc.title = @"头条"; //添加 [self addChildViewController:lvc];}
代码块二:设置按钮
#pragma mark - 设置按钮- (void)setWithBtn{ //拿到标题view的所有的子控件数 NSInteger count = self.titleView.subviews.count; //遍历控件 for (int i = 0; i < count; i++) { //取到对应的按钮 UIButton *btn = self.titleView.subviews[i]; //获取对应的控制器 UIViewController *vc = self.childViewControllers[i]; //设置按钮对应的标题 [btn setTitle:vc.title forState:UIControlStateNormal]; } }
代码块三:处理点击按钮的业务逻辑(采用直接拖线的方法)
#pragma mark - 按钮的业务逻辑- (IBAction)titleBtnClick:(UIButton *)sender{ //遍历contentView中所有的子控制器(移除多余的控制器view,只保证只有一个view) for (UIView *view in self.contentView.subviews) { NSLog(@"%@",self.contentView.subviews); [view removeFromSuperview]; } //根据tag.选择指定的控制器 UIViewController *vc = self.childViewControllers[sender.tag]; //设置控制器view的背景颜色 vc.view.backgroundColor = sender.backgroundColor; //设置控制器view的尺寸 vc.view.frame = self.contentView.bounds; //将控制器的view加入到contentView中 [self.contentView addSubview:vc.view];}
代码块四:设置一个view,用来装子控件的view(占位思想精华部分)
/** * 用来接收控制器的view */@property (weak, nonatomic) IBOutlet UIView *contentView;
5 其实上面的思想是用到了占位的思想,就是先用一个view将父控件的view占住一个位置,然后通过占据的位置来处理业务,通常是在开发中常用的一种思想.
二 MJ框架底层RunTime思想(二级模型转换)
条件:当模型中嵌套了一个模型的时候,也就是说字典中又含有字典的时候,需要我们做二级转换.
步骤:
—-> 1 遍历模型中的属性
—-> 2 判断属性的类型是否是字典的类型,满足条件才可以二级转换
—-> 3 如果是,字典的类型,那么就调用自己实现一级模型转换
—-> 4 根据key和value给模型属性赋值
底层的代码部分:
+ (instancetype)modelWithDict:(NSDictionary *)dict{ //遍历模型中的属性,用字典中的属性给模型属性赋值 //先创建一个模型 id obj = [[self alloc] init]; //初始化成员变量总数 NSInteger count = 0; //取出成员属性列表(是一个数组) Ivar *ivarList = class_copyIvarList(self, &count); //遍历 for (int i = 0; i < count; i++) { //获取成员变量 Ivar ivar = ivarList[i]; //获取成员变量的名称 NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)]; //获取成员变量的类型 NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)]; //替换(由于获取的成员变量的类型格式是@"\User\"这种类型的,需要我们将@"和\"替换掉) type = [type stringByReplacingOccurrencesOfString:@"@\"" withString:@""]; type = [type stringByReplacingOccurrencesOfString:@"\"" withString:@""]; //将成员变量的下划线截去掉 NSString *key = [ivarName substringFromIndex:1]; //从字典中取出对应的value(根据key) id value = dict[key]; //判断只有是字典并且是自定义的才需要二级转换 if ([value isKindOfClass:[NSDictionary class]] && ![type containsString:@"NS"]) { //获取类型 Class className = NSClassFromString(type); //字典转模型 value = [className modelWithDict:dict]; } if (value) { //用key和value给模型中的属性赋值 [obj setValue:value forKey:key]; } } return obj;}
三 总结
1 知道了MJ框架的底层实现,那么我们可以更加巧妙的利用MJ框架进行一些复杂的模型转换,同时我们甚至可以自己写框架,前提是有足够繁多的知识积累.
2 在开发中需要知道,当我们需要另外一种格式的控制器时,又想要和UITabBarController一样的功能的时候,我们完全可以自定义一个,同样而已达到功能的实现.
3 在开发中还有很多的不懂的地方,希望大家多多指教,谢谢!!!!
1 0
- 父子控制器和MJ框架底层RunTime思想(二)
- yii2框架(二):控制器和视图
- spring开思想-框架底层思想
- 父子控制器
- 父子控制器
- 父子控制器
- 父子控制器
- 父子控制器
- 父子控制器
- 父子控制器
- 类反射学习(二)JAVA开发框架底层思想演示,以及类反射的应用
- Runtime底层
- 父子控制器1
- 浅谈父子控制器
- 父子控制器总结
- object-c底层(类和对象,runtime)
- Spring Web MVC框架(二) 控制器
- JAVA 开发平台的技术和框架(二)前端控制器:Struts2 ,Spring MVC
- ListVIew实现预加载效果
- java常见问题
- tcp状态
- @date2016-03-27(软件工程男的日常)
- java代码规范总结
- 父子控制器和MJ框架底层RunTime思想(二)
- sbringMVC配置1
- Android解析——json解析为javabean
- 《MongoDB GridFS最佳应用概述》
- C++实验二—分段函数求值
- Socket实现刷新好友
- springMVC2
- 信号(互)相关及其应用
- Android开发中从url中加载图片