[注意]转载请注明出处:吃唐僧肉的小悟空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;91011self.head.image =[UIImage imageNamed:appViewModel.icon];12self.nameLabel.text =appViewModel.name;131415}16*这样我们就可以在控制器中直接赋值模型,然后显示数据17//2.4赋值18AppViewModel *appViewModel =self.apps[i];192021appOldView.appViewModel =appViewModel;2223242526279. 封装创建View的代码, 让用户不知道是通过xib创建的还是通过代码创建的,安全,扩展性比较好。28*封装一个类方法29+(instancetype )loadNib{30return[[NSBundle mainBundle]loadNibNamed:@"appView"owner:nil options:nil][0];31323334}
[注意]转载请注明出处:吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/
附上程序源代码:
KZAppView.h
1//2//KZAppModel.h3//UI基础-03-05-144//5//Created by hukezhu on 15/5/15.6//7//89#import<Foundation/Foundation.h>10/*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/11@interfaceKZAppModel : NSObject12/**13* 应用图标14*/15@PRoperty (nonatomic ,copy) NSString *icon;16/**17* 应用名称18*/19@property (nonatomic ,copy) NSString *name;2021/**22* 通过字典来初始化对象23*24* @param dict 字典对象25*26* @return 已经初始化完毕的模型对象27*/28- (instancetype)initWithDict:(NSDictionary *)dict;2930//类方法31+ (instancetype)appWithModelDict:(NSDictionary *)dict;3233@end
KZAppView.m
1//2//KZAppModel.m3//UI基础-03-05-144//5//Created by hukezhu on 15/5/15.6//7//89#import"KZAppModel.h"1011@implementationKZAppModel12/*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/13//对象方法14-(instancetype)initWithDict:(NSDictionary *)dict{1516//重写构造方法的默认写法17if(self =[super init]){1819//将字典的所有属性赋值给模型20self.icon = dict[@"icon"];21self.name = dict[@"name"];22}23returnself;24}25//类方法26+(instancetype)appWithModelDict:(NSDictionary *)dict{2728//注意此处是self29return[[self alloc]initWithDict:dict];30}31@end
描述xib文件的AppView.h和AppView.m文件
AppView.h:
1//2//AppView.h3//UI基础-03-05-144//5//Created by hukezhu on 15/5/15.6//7//转载请注明出处:吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/89#import<UIKit/UIKit.h>10@classKZAppModel;11@interfaceAppView : UIView1213//声明一个模型属性,用来接收传过来的模型数据14@property (nonatomic,strong)KZAppModel *appViewModel;1516//用来加载xib17+(instancetype)loadNib;18@end
AppView.m
1//2//AppView.m3//UI基础-03-05-144//5//Created by hukezhu on 15/5/15.6//7//转载请注明出处:吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/89#import"AppView.h"10#import"KZAppModel.h"11@interfaceAppView ()12@property (nonatomic,weak)IBOutlet UIImageView *imageView;13@property (weak, nonatomic) IBOutlet UILabel *label;1415-(IBAction)btnOnClick:(UIButton *)btn;16@end171819@implementationAppView20//重写模型的set方法21-(void)setAppViewModel:(KZAppModel *)appViewModel{2223_appViewModel =appViewModel;24self.imageView.image =[UIImage imageNamed:appViewModel.icon];25self.label.text =appViewModel.name;26}272829+(instancetype)loadNib{3031return[[NSBundle mainBundle]loadNibNamed:@"AppView"owner:nil options:nil][0];32}333435/*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/36/**37* 按钮的点击方法38*39* @param btn 将按钮本身传入方法中,哪个按钮被点击就调用这个方法40*/41- (void)btnOnClick:(UIButton *)btn{4243//NSLog(@"------%@",btn);44btn.enabled =NO;45[btn setTitle:@"已下载"forState:UIControlStateNormal];4647CGFloat labelW =120;48CGFloat labelH =30;49CGFloat labelX = (self.superview.frame.size.width - labelW)*0.5;50CGFloat labelY = (self.superview.frame.size.height - labelH)*0.5;51UILabel *label =[[UILabel alloc]init];52label.frame =CGRectMake(labelX, labelY, labelW, labelH);53label.text =@"正在下载";54//设置字体颜色55label.textColor =[UIColor redColor];56//设置字体居中57label.textAlignment =NSTextAlignmentCenter;58//设置 背景色59label.backgroundColor =[UIColor blackColor];6061//设置圆角的半径62label.layer.cornerRadius =8;63//将多余的部分减掉64label.layer.masksToBounds =YES;65//设置透明度66label.alpha =0.0;67//将label添加到view中68[self.superview addSubview:label];69//使用block动画,动画持续时间2秒70[UIView animateWithDuration:2.0animations:^{71label.alpha =0.5;72} completion:^(BOOL finished) {73if(finished) {74[UIView animateWithDuration:2.0delay:0.1options:UIViewAnimationOptionCurveLinear animations:^{75label.alpha =0.0;76} completion:^(BOOL finished) {77//上面将透明度设置为0,界面上已经不显示这个label,但是它仍然在内存中,所以为了节约内存,仍要将其从内存中删除78[label removeFromSuperview];7980}];81}82}];8384}8586@end
ViewController.m
1//2//ViewController.m3//03-应用管理4//5//Created by hukezhu on 15/5/14.6//7//89#import"ViewController.h"10#import"KZAppModel.h"11#import"AppView.h"1213@interfaceViewController ()14@property (nonatomic,strong)NSArray *apps;15@end1617@implementationViewController1819- (void)viewDidLoad {20[super viewDidLoad];2122//每一行的应用的个数23inttotalCol =3;24/*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/2526//添加一个小的view27CGFloat appW =80;28CGFloat appH =100;29CGFloat marginX =20;30CGFloat marginY =20;31CGFloat hightMargin =30;32CGFloat leftMargin = (self.view.frame.size.width - totalCol * appW - (totalCol -1) *marginX)*0.5;33343536for(inti =0; i < self.apps.count; i++) {373839//计算行号和列号40introw = i /totalCol;41intcol = i %totalCol;4243CGFloat appX = leftMargin + (marginX + appW)*col;44CGFloat appY = hightMargin + (marginY + appH)*row;4546//1.添加view474849//首先拿到一个格子视图50//UIView *appView = [[NSBundle mainBundle]loadNibNamed:@"AppView" owner:nil options:nil][0];5152AppView *appView =[AppView loadNib];535455//1.2设置frame56appView.frame =CGRectMake(appX, appY, appW, appH);57//1.3设置背景色(便于代码阶段验证,之后会删除)58//appView.backgroundColor = [UIColor redColor];59//1.4将这个appView添加到view中60[self.view addSubview:appView];6162//加载数据63//NSDictionary *dict = self.apps[i];64//将数据赋值给模型对象65KZAppModel *appModel =self.apps[i];666768//通过数组的特性拿到里面的小控件,进行赋值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;747576appView.appViewModel =appModel;7778798081//UIButton *downBtn = (UIButton *)appView.subviews[2];82//[downBtn addTarget:self action:@selector(btnOnClick:) forControlEvents:UIControlEventTouchUpInside];838485////2.添加图片UIImageView86//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////从模型对象中取出数据name110//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}143144145146147148}149/**150* "懒加载",加载应用数据151*152*/153- (NSArray *)apps{154155//如果_apps为空,才加载数据156if(_apps ==nil) {157//获取plist的全路径158NSString *path = [[NSBundle mainBundle]pathForResource:@"app.plist"ofType:nil];159160//加载数组161NSArray *dictArray =[NSArray arrayWithContentsOfFile:path];162163//创建一个可变数组,来动态接收模型对象164NSMutableArray *array =[NSMutableArray array];165166//通过循环,将字典数组的字典取出,转成模型对象167for(NSDictionary *dictindictArray) {168KZAppModel *appModel =[KZAppModel appWithModelDict:dict];169[array addObject:appModel];170}171_apps =array;172}173return_apps;174/*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/175}176177- (void)didReceiveMemoryWarning {178[super didReceiveMemoryWarning];179//Dispose of any resources that can be recreated.180}181182@end
这个应用管理小应用的代码目前就改进到此,代码中还有不合适的地方,以后再来改进.这个小实例比较综合,利用到了前面所说的知识,熟练掌握的话对后续深层次的学习大有好处.
转载请注明出处:博客园--吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/