[注意]转载请注明出处:吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/
上篇文章结尾介绍了一下为什么要对xib进行封装,这里不再赘述.
大体整理了一下封装的思路(我自己的想法,可能不是很清晰):
为了扩展,将xib的代码封装,创建一个类,来描述xib
>在新建的.m文件中,新建一个类扩展(类似于viewController)
>在新建的.h文件中,加入一个模型的属性(@class)
>在新建的.m文件中,重写模型的set方法(在.h文件中已经加入了,自动生成了set/get方法)(#import)
>加载xib的方法在控制器中,假设多个控制器使用,为了扩展性好,封装到新建的类中,写一个类方法来实现加载xib
>在控制器中调用的时候,直接使用类方法即可.
使用xib,将应用管理的界面,搭建出来,在控制器中通过NSBundle获取xib数据(返回一个数组),然后获取其中的控件,分别赋值.
此时,考虑到多控制器使用的话,每个控制器都要写相同的代码(获取xib,更新数据,而且假设要扩展的话,每个都要修改),为了扩展性好,新建一个类来描述xib(类似于 viewcontroller文件描述storyboard一样),在这个新建的类中进行xib中的赋值,但是数据在控制器的模型中,所以先要得到数据.所以,在新建的类中要加一个模型的 属性,在新建的类的.m文件中,重写模型属性的set方法,在这个set方法中进行赋值.
在控制器中使用的时候,首先获取这个xib文件,注意返回的是一个新的view(新建的类),然后再后边,将数据赋值给创建的类的模型的属性即可
再次将xib文件的获取方法,进行封装,封装到新建的类中,写一个类方法,使用的时候直接调用类方法
应用代码结构截图:
xib文件拖线截图:
1 自定义View。创建属性、传递Model进去。 2 *自定义一个appview用来描述xib,然后我们需要把xib的真实类型改变为appview(必须有这一步) 3 *用拖线的方式拿到里面的三个小的控件 4 *给这些控件进行赋数据,数据在模型中,我们拥有一个模型属性,为了从控制器中拿到模型,我们重写模型的set方法, 5 这样我们就可以通过set方法把控制器中的模型数据赋值给我们内部的模型,拿到模型后我们进行控件的赋值, 6 //重写模型的set方法 7 - (void)setAppViewModel:(AppViewModel *)appViewModel{ 8 _appViewModel = appViewModel; 9 10 11 self.head.image = [UIImage imageNamed:appViewModel.icon]; 12 self.nameLabel.text = appViewModel.name; 13 14 15 } 16 *这样我们就可以在控制器中直接赋值模型,然后显示数据 17 // 2.4赋值 18 AppViewModel *appViewModel = self.apps[i]; 19 20 21 appOldView.appViewModel = appViewModel; 22 23 24 25 26 27 9. 封装创建View的代码, 让用户不知道是通过xib创建的还是通过代码创建的,安全,扩展性比较好。 28 * 封装一个类方法 29 + (instancetype )loadNib{ 30 return [[NSBundle mainBundle]loadNibNamed:@"appView" owner:nil options:nil][0]; 31 32 33 34 }
[注意]转载请注明出处:吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/
附上程序源代码:
KZAppView.h
1 // 2 // KZAppModel.h 3 // UI基础-03-05-14 4 // 5 // Created by hukezhu on 15/5/15. 6 // 7 // 8 9 #import <Foundation/Foundation.h> 10 /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/ 11 @interface KZAppModel : NSObject 12 /** 13 * 应用图标 14 */ 15 @property (nonatomic ,copy) NSString *icon; 16 /** 17 * 应用名称 18 */ 19 @property (nonatomic ,copy) NSString *name; 20 21 /** 22 * 通过字典来初始化对象 23 * 24 * @param dict 字典对象 25 * 26 * @return 已经初始化完毕的模型对象 27 */ 28 - (instancetype)initWithDict:(NSDictionary *)dict; 29 30 //类方法 31 + (instancetype)appWithModelDict:(NSDictionary *)dict; 32 33 @end
KZAppView.m
1 // 2 // KZAppModel.m 3 // UI基础-03-05-14 4 // 5 // Created by hukezhu on 15/5/15. 6 // 7 // 8 9 #import "KZAppModel.h" 10 11 @implementation KZAppModel 12 /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/ 13 //对象方法 14 -(instancetype)initWithDict:(NSDictionary *)dict{ 15 16 //重写构造方法的默认写法 17 if(self = [super init]){ 18 19 //将字典的所有属性赋值给模型 20 self.icon = dict[@"icon"]; 21 self.name = dict[@"name"]; 22 } 23 return self; 24 } 25 //类方法 26 +(instancetype)appWithModelDict:(NSDictionary *)dict{ 27 28 //注意此处是self 29 return [[self alloc]initWithDict:dict]; 30 } 31 @end
描述xib文件的AppView.h和AppView.m文件
AppView.h:
1 // 2 // AppView.h 3 // UI基础-03-05-14 4 // 5 // Created by hukezhu on 15/5/15. 6 // 7 //转载请注明出处:吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/ 8 9 #import <UIKit/UIKit.h> 10 @class KZAppModel; 11 @interface AppView : UIView 12 13 //声明一个模型属性,用来接收传过来的模型数据 14 @property (nonatomic,strong)KZAppModel *appViewModel; 15 16 //用来加载xib 17 +(instancetype)loadNib; 18 @end
AppView.m
1 // 2 // AppView.m 3 // UI基础-03-05-14 4 // 5 // Created by hukezhu on 15/5/15. 6 // 7 //转载请注明出处:吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/ 8 9 #import "AppView.h" 10 #import "KZAppModel.h" 11 @interface AppView () 12 @property (nonatomic,weak)IBOutlet UIImageView *imageView; 13 @property (weak, nonatomic) IBOutlet UILabel *label; 14 15 -(IBAction)btnOnClick:(UIButton *)btn; 16 @end 17 18 19 @implementation AppView 20 //重写模型的set方法 21 -(void)setAppViewModel:(KZAppModel *)appViewModel{ 22 23 _appViewModel = appViewModel; 24 self.imageView.image = [UIImage imageNamed:appViewModel.icon]; 25 self.label.text = appViewModel.name; 26 } 27 28 29 +(instancetype)loadNib{ 30 31 return [[NSBundle mainBundle]loadNibNamed:@"AppView" owner:nil options:nil][0]; 32 } 33 34 35 /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/ 36 /** 37 * 按钮的点击方法 38 * 39 * @param btn 将按钮本身传入方法中,哪个按钮被点击就调用这个方法 40 */ 41 - (void)btnOnClick:(UIButton *)btn{ 42 43 //NSLog(@"------%@",btn); 44 btn.enabled = NO; 45 [btn setTitle:@"已下载" forState:UIControlStateNormal]; 46 47 CGFloat labelW = 120; 48 CGFloat labelH = 30; 49 CGFloat labelX = (self.superview.frame.size.width - labelW)* 0.5; 50 CGFloat labelY = (self.superview.frame.size.height - labelH)*0.5; 51 UILabel *label = [[UILabel alloc]init]; 52 label.frame = CGRectMake(labelX, labelY, labelW, labelH); 53 label.text = @"正在下载"; 54 //设置字体颜色 55 label.textColor = [UIColor redColor]; 56 //设置字体居中 57 label.textAlignment = NSTextAlignmentCenter; 58 //设置 背景色 59 label.backgroundColor = [UIColor blackColor]; 60 61 //设置圆角的半径 62 label.layer.cornerRadius = 8; 63 //将多余的部分减掉 64 label.layer.masksToBounds = YES; 65 //设置透明度 66 label.alpha = 0.0; 67 //将label添加到view中 68 [self.superview addSubview:label]; 69 //使用block动画,动画持续时间2秒 70 [UIView animateWithDuration:2.0 animations:^{ 71 label.alpha = 0.5; 72 } completion:^(BOOL finished) { 73 if (finished) { 74 [UIView animateWithDuration:2.0 delay:0.1 options:UIViewAnimationOptionCurveLinear animations:^{ 75 label.alpha = 0.0; 76 } completion:^(BOOL finished) { 77 //上面将透明度设置为0,界面上已经不显示这个label,但是它仍然在内存中,所以为了节约内存,仍要将其从内存中删除 78 [label removeFromSuperview]; 79 80 }]; 81 } 82 }]; 83 84 } 85 86 @end
ViewController.m
1 // 2 // ViewController.m 3 // 03-应用管理 4 // 5 // Created by hukezhu on 15/5/14. 6 // 7 // 8 9 #import "ViewController.h" 10 #import "KZAppModel.h" 11 #import "AppView.h" 12 13 @interface ViewController () 14 @property (nonatomic,strong)NSArray *apps; 15 @end 16 17 @implementation ViewController 18 19 - (void)viewDidLoad { 20 [super viewDidLoad]; 21 22 //每一行的应用的个数 23 int totalCol = 3; 24 /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/ 25 26 //添加一个小的view 27 CGFloat appW = 80; 28 CGFloat appH = 100; 29 CGFloat marginX = 20; 30 CGFloat marginY = 20; 31 CGFloat hightMargin = 30; 32 CGFloat leftMargin = (self.view.frame.size.width - totalCol * appW - (totalCol - 1) *marginX)* 0.5; 33 34 35 36 for (int i = 0; i < self.apps.count; i++) { 37 38 39 //计算行号和列号 40 int row = i / totalCol; 41 int col = i % totalCol; 42 43 CGFloat appX = leftMargin + (marginX + appW)* col; 44 CGFloat appY = hightMargin + (marginY + appH)* row; 45 46 //1.添加view 47 48 49 //首先拿到一个格子视图 50 // UIView *appView = [[NSBundle mainBundle]loadNibNamed:@"AppView" owner:nil options:nil][0]; 51 52 AppView *appView = [AppView loadNib]; 53 54 55 //1.2设置frame 56 appView.frame = CGRectMake(appX, appY, appW, appH); 57 //1.3设置背景色(便于代码阶段验证,之后会删除) 58 //appView.backgroundColor = [UIColor redColor]; 59 //1.4将这个appView添加到view中 60 [self.view addSubview:appView]; 61 62 //加载数据 63 //NSDictionary *dict = self.apps[i]; 64 //将数据赋值给模型对象 65 KZAppModel *appModel = self.apps[i]; 66 67 68 //通过数组的特性拿到里面的小控件,进行赋值 69 // UIImageView *imageView = (UIImageView *)appView.subviews[0]; 70 // imageView.image = [UIImage imageNamed:appModel.icon]; 71 // 72 // UILabel *label = appView.subviews[1]; 73 // label.text = appModel.name; 74 75 76 appView.appViewModel = appModel; 77 78 79 80 81 // UIButton *downBtn = (UIButton *)appView.subviews[2]; 82 // [downBtn addTarget:self action:@selector(btnOnClick:) forControlEvents:UIControlEventTouchUpInside]; 83 84 85 // //2.添加图片UIImageView 86 // CGFloat imageW = 60; 87 // CGFloat imageH = 50; 88 // CGFloat imageX = (appW - imageW)*0.5; 89 // CGFloat imageY = 0; 90 // UIImageView *imageView = [[UIImageView alloc]init]; 91 // imageView.frame = CGRectMake(imageX, imageY, imageW, imageH); 92 // //imageView.backgroundColor = [UIColor blueColor]; 93 // //imageView.image = [UIImage imageNamed:dict[@"icon"]]; 94 // //从模型对象中取出数据 95 // imageView.image = [UIImage imageNamed:appModel.icon]; 96 // [appView addSubview:imageView]; 97 // 98 // 99 // //3.添加应用名称 100 // 101 // CGFloat labelW = 80; 102 // CGFloat labelH = 25; 103 // CGFloat labelX = 0; 104 // CGFloat labelY = imageH; 105 // UILabel *label = [[UILabel alloc]init]; 106 // label.frame = CGRectMake(labelX, labelY, labelW, labelH); 107 // //label.backgroundColor = [UIColor grayColor]; 108 // //label.text = dict[@"name"]; 109 // //从模型对象中取出数据name 110 // label.text = appModel.name; 111 // 112 // //设置字体大小 113 // label.font = [UIFont systemFontOfSize:13]; 114 // //设置字体居中 115 // label.textAlignment = NSTextAlignmentCenter; 116 // [appView addSubview:label]; 117 // 118 // //4.添加下载按钮 119 // 120 // CGFloat downloadW = 60; 121 // CGFloat downloadH = 25; 122 // CGFloat downloadX = 10; 123 // CGFloat downloadY = labelH + labelY; 124 // UIButton *downloadBtn = [[UIButton alloc]init]; 125 // downloadBtn.frame = CGRectMake(downloadX, downloadY, downloadW, downloadH); 126 // //downloadBtn.backgroundColor = [UIColor yellowColor]; 127 // //设置背景图片 128 // [downloadBtn setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal]; 129 // [downloadBtn setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted]; 130 // //设置字体第一种方法 131 // [downloadBtn setTitle:@"下载" forState:UIControlStateNormal]; 132 // 133 // //设置字体第二种方法(不推荐使用) 134 // downloadBtn.titleLabel.text = @"下载"; 135 // 136 // //设置字体大小 137 // downloadBtn.titleLabel.font = [UIFont systemFontOfSize:15]; 138 // [appView addSubview:downloadBtn]; 139 // 140 // 141 // [downloadBtn addTarget:self action:@selector(btnOnClick:) forControlEvents:UIControlEventTouchUpInside]; 142 } 143 144 145 146 147 148 } 149 /** 150 * "懒加载",加载应用数据 151 * 152 */ 153 - (NSArray *)apps{ 154 155 //如果_apps为空,才加载数据 156 if (_apps == nil) { 157 //获取plist的全路径 158 NSString *path = [[NSBundle mainBundle]pathForResource:@"app.plist" ofType:nil]; 159 160 //加载数组 161 NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; 162 163 //创建一个可变数组,来动态接收模型对象 164 NSMutableArray *array = [NSMutableArray array]; 165 166 //通过循环,将字典数组的字典取出,转成模型对象 167 for (NSDictionary *dict in dictArray) { 168 KZAppModel *appModel = [KZAppModel appWithModelDict:dict]; 169 [array addObject:appModel]; 170 } 171 _apps = array; 172 } 173 return _apps; 174 /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/ 175 } 176 177 - (void)didReceiveMemoryWarning { 178 [super didReceiveMemoryWarning]; 179 // Dispose of any resources that can be recreated. 180 } 181 182 @end
这个应用管理小应用的代码目前就改进到此,代码中还有不合适的地方,以后再来改进.这个小实例比较综合,利用到了前面所说的知识,熟练掌握的话对后续深层次的学习大有好处.
转载请注明出处:博客园--吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/