[注意]轉(zhuǎn)載請注明出處:吃唐僧肉的小悟空http://www.survivalescaperooms.com/hukezhu/
上篇文章結(jié)尾介紹了一下為什么要對xib進(jìn)行封裝,這里不再贅述.
大體整理了一下封裝的思路(我自己的想法,可能不是很清晰):
為了擴(kuò)展,將xib的代碼封裝,創(chuàng)建一個類,來描述xib
>在新建的.m文件中,新建一個類擴(kuò)展(類似于viewController)
>在新建的.h文件中,加入一個模型的屬性(@class)
>在新建的.m文件中,重寫模型的set方法(在.h文件中已經(jīng)加入了,自動生成了set/get方法)(#import)
>加載xib的方法在控制器中,假設(shè)多個控制器使用,為了擴(kuò)展性好,封裝到新建的類中,寫一個類方法來實(shí)現(xiàn)加載xib
>在控制器中調(diào)用的時候,直接使用類方法即可.
使用xib,將應(yīng)用管理的界面,搭建出來,在控制器中通過NSBundle獲取xib數(shù)據(jù)(返回一個數(shù)組),然后獲取其中的控件,分別賦值.
此時,考慮到多控制器使用的話,每個控制器都要寫相同的代碼(獲取xib,更新數(shù)據(jù),而且假設(shè)要擴(kuò)展的話,每個都要修改),為了擴(kuò)展性好,新建一個類來描述xib(類似于 viewcontroller文件描述storyboard一樣),在這個新建的類中進(jìn)行xib中的賦值,但是數(shù)據(jù)在控制器的模型中,所以先要得到數(shù)據(jù).所以,在新建的類中要加一個模型的 屬性,在新建的類的.m文件中,重寫模型屬性的set方法,在這個set方法中進(jìn)行賦值.
在控制器中使用的時候,首先獲取這個xib文件,注意返回的是一個新的view(新建的類),然后再后邊,將數(shù)據(jù)賦值給創(chuàng)建的類的模型的屬性即可
再次將xib文件的獲取方法,進(jìn)行封裝,封裝到新建的類中,寫一個類方法,使用的時候直接調(diào)用類方法
應(yīng)用代碼結(jié)構(gòu)截圖:

xib文件拖線截圖:

1 自定義View。創(chuàng)建屬性、傳遞Model進(jìn)去。 2 *自定義一個appview用來描述xib,然后我們需要把xib的真實(shí)類型改變?yōu)閍ppview(必須有這一步) 3 *用拖線的方式拿到里面的三個小的控件 4 *給這些控件進(jìn)行賦數(shù)據(jù),數(shù)據(jù)在模型中,我們擁有一個模型屬性,為了從控制器中拿到模型,我們重寫模型的set方法, 5 這樣我們就可以通過set方法把控制器中的模型數(shù)據(jù)賦值給我們內(nèi)部的模型,拿到模型后我們進(jìn)行控件的賦值, 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 *這樣我們就可以在控制器中直接賦值模型,然后顯示數(shù)據(jù)17 // 2.4賦值18 AppViewModel *appViewModel = self.apps[i];19 20 21 appOldView.appViewModel = appViewModel;22 23 24 25 26 27 9. 封裝創(chuàng)建View的代碼, 讓用戶不知道是通過xib創(chuàng)建的還是通過代碼創(chuàng)建的,安全,擴(kuò)展性比較好。28 * 封裝一個類方法29 + (instancetype )loadNib{30 return [[NSBundle mainBundle]loadNibNamed:@"appView" owner:nil options:nil][0];31 32 33 34 }
[注意]轉(zhuǎn)載請注明出處:吃唐僧肉的小悟空http://www.survivalescaperooms.com/hukezhu/
附上程序源代碼:
KZAppView.h
1 // 2 // KZAppModel.h 3 // UI基礎(chǔ)-03-05-14 4 // 5 // Created by hukezhu on 15/5/15. 6 // 7 // 8 9 #import <Foundation/Foundation.h>10 /*吃唐僧肉的小悟空-轉(zhuǎn)載請注明出處http://www.survivalescaperooms.com/hukezhu/*/11 @interface KZAppModel : NSObject12 /**13 * 應(yīng)用圖標(biāo)14 */15 @PRoperty (nonatomic ,copy) NSString *icon;16 /**17 * 應(yīng)用名稱18 */19 @property (nonatomic ,copy) NSString *name;20 21 /**22 * 通過字典來初始化對象23 *24 * @param dict 字典對象25 *26 * @return 已經(jīng)初始化完畢的模型對象27 */28 - (instancetype)initWithDict:(NSDictionary *)dict;29 30 //類方法31 + (instancetype)appWithModelDict:(NSDictionary *)dict;32 33 @end
KZAppView.m
1 // 2 // KZAppModel.m 3 // UI基礎(chǔ)-03-05-14 4 // 5 // Created by hukezhu on 15/5/15. 6 // 7 // 8 9 #import "KZAppModel.h"10 11 @implementation KZAppModel12 /*吃唐僧肉的小悟空-轉(zhuǎn)載請注明出處http://www.survivalescaperooms.com/hukezhu/*/13 //對象方法14 -(instancetype)initWithDict:(NSDictionary *)dict{15 16 //重寫構(gòu)造方法的默認(rèn)寫法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 //注意此處是self29 return [[self alloc]initWithDict:dict];30 }31 @end
描述xib文件的AppView.h和AppView.m文件
AppView.h:
1 // 2 // AppView.h 3 // UI基礎(chǔ)-03-05-14 4 // 5 // Created by hukezhu on 15/5/15. 6 // 7 //轉(zhuǎn)載請注明出處:吃唐僧肉的小悟空http://www.survivalescaperooms.com/hukezhu/ 8 9 #import <UIKit/UIKit.h>10 @class KZAppModel;11 @interface AppView : UIView12 13 //聲明一個模型屬性,用來接收傳過來的模型數(shù)據(jù)14 @property (nonatomic,strong)KZAppModel *appViewModel;15 16 //用來加載xib17 +(instancetype)loadNib;18 @end
AppView.m
1 // 2 // AppView.m 3 // UI基礎(chǔ)-03-05-14 4 // 5 // Created by hukezhu on 15/5/15. 6 // 7 //轉(zhuǎn)載請注明出處:吃唐僧肉的小悟空http://www.survivalescaperooms.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 @end17 18 19 @implementation AppView20 //重寫模型的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 /*吃唐僧肉的小悟空-轉(zhuǎn)載請注明出處http://www.survivalescaperooms.com/hukezhu/*/36 /**37 * 按鈕的點(diǎn)擊方法38 *39 * @param btn 將按鈕本身傳入方法中,哪個按鈕被點(diǎn)擊就調(diào)用這個方法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 //設(shè)置字體顏色55 label.textColor = [UIColor redColor];56 //設(shè)置字體居中57 label.textAlignment = NSTextAlignmentCenter;58 //設(shè)置 背景色59 label.backgroundColor = [UIColor blackColor];60 61 //設(shè)置圓角的半徑62 label.layer.cornerRadius = 8;63 //將多余的部分減掉64 label.layer.masksToBounds = YES;65 //設(shè)置透明度66 label.alpha = 0.0;67 //將label添加到view中68 [self.superview addSubview:label];69 //使用block動畫,動畫持續(xù)時間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 //上面將透明度設(shè)置為0,界面上已經(jīng)不顯示這個label,但是它仍然在內(nèi)存中,所以為了節(jié)約內(nèi)存,仍要將其從內(nèi)存中刪除78 [label removeFromSuperview];79 80 }];81 }82 }];83 84 }85 86 @end
ViewController.m
1 // 2 // ViewController.m 3 // 03-應(yīng)用管理 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 //每一行的應(yīng)用的個數(shù) 23 int totalCol = 3; 24 /*吃唐僧肉的小悟空-轉(zhuǎn)載請注明出處http://www.survivalescaperooms.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設(shè)置frame 56 appView.frame = CGRectMake(appX, appY, appW, appH); 57 //1.3設(shè)置背景色(便于代碼階段驗證,之后會刪除) 58 //appView.backgroundColor = [UIColor redColor]; 59 //1.4將這個appView添加到view中 60 [self.view addSubview:appView]; 61 62 //加載數(shù)據(jù) 63 //NSDictionary *dict = self.apps[i]; 64 //將數(shù)據(jù)賦值給模型對象 65 KZAppModel *appModel = self.apps[i]; 66 67 68 //通過數(shù)組的特性拿到里面的小控件,進(jìn)行賦值 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 // //從模型對象中取出數(shù)據(jù) 95 // imageView.image = [UIImage imageNamed:appModel.icon]; 96 // [appView addSubview:imageView]; 97 // 98 // 99 // //3.添加應(yīng)用名稱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 // //從模型對象中取出數(shù)據(jù)name110 // label.text = appModel.name;111 // 112 // //設(shè)置字體大小113 // label.font = [UIFont systemFontOfSize:13];114 // //設(shè)置字體居中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 // //設(shè)置背景圖片128 // [downloadBtn setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];129 // [downloadBtn setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted];130 // //設(shè)置字體第一種方法131 // [downloadBtn setTitle:@"下載" forState:UIControlStateNormal];132 // 133 // //設(shè)置字體第二種方法(不推薦使用)134 // downloadBtn.titleLabel.text = @"下載";135 // 136 // //設(shè)置字體大小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 * "懶加載",加載應(yīng)用數(shù)據(jù)151 *152 */153 - (NSArray *)apps{154 155 //如果_apps為空,才加載數(shù)據(jù)156 if (_apps == nil) {157 //獲取plist的全路徑158 NSString *path = [[NSBundle mainBundle]pathForResource:@"app.plist" ofType:nil];159 160 //加載數(shù)組161 NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];162 163 //創(chuàng)建一個可變數(shù)組,來動態(tài)接收模型對象164 NSMutableArray *array = [NSMutableArray array];165 166 //通過循環(huán),將字典數(shù)組的字典取出,轉(zhuǎn)成模型對象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 /*吃唐僧肉的小悟空-轉(zhuǎn)載請注明出處http://www.survivalescaperooms.com/hukezhu/*/175 }176 177 - (void)didReceiveMemoryWarning {178 [super didReceiveMemoryWarning];179 // Dispose of any resources that can be recreated.180 }181 182 @end
這個應(yīng)用管理小應(yīng)用的代碼目前就改進(jìn)到此,代碼中還有不合適的地方,以后再來改進(jìn).這個小實(shí)例比較綜合,利用到了前面所說的知識,熟練掌握的話對后續(xù)深層次的學(xué)習(xí)大有好處.
轉(zhuǎn)載請注明出處:博客園--吃唐僧肉的小悟空http://www.survivalescaperooms.com/hukezhu/
新聞熱點(diǎn)
疑難解答