[注意]转载时请注明出处博客园-吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/
前几篇文章介绍了一个应用管理的小应用,从最开始的单纯实现功能,一步一步就行改进封装,上篇文章是使用xib进行了优化,本篇文章使用代理实现监听下载按钮的点击.
在原来的基础上,使用代理的主要思路分析:
-
- 首先要新建一个协议
- 声明协议的要实现的方法(一般为optional)
- 声明一个遵守该协议的代理的属性
- 使用代理,通知其代理完成操作
在代理中的实现步骤:
-
- 遵守协议
- 设置代理(一般通过拖线也可以实现)
- 实现代理中需要实现的方法
附上应用代码结构及xib截图:
附上源代码:
AppView.h
1 // 2 // AppView.h 3 // UI基础-03-05-14 4 // 5 // Created by hukezhu on 15/5/15. 6 // 7 // 8 9 #import <UIKit/UIKit.h> 10 @class KZAppModel; 11 @class AppView; 12 13 14 15 @protocol AppViewProtocol <NSObject> 16 17 - (void)appViewDownload:(AppView *)appView; 18 19 @end 20 21 22 23 24 25 @interface AppView : UIView 26 27 //声明一个模型属性,用来接收传过来的模型数据 28 @property (nonatomic,strong)KZAppModel *appViewModel; 29 30 31 //声明一个代理的属性 32 @property(nonatomic,assign) id<AppViewProtocol> delegate; 33 34 //用来加载xib 35 +(instancetype)loadNib; 36 @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 if ([self.delegate respondsToSelector:@selector(appViewDownload:)]) { 48 [self.delegate appViewDownload:self]; 49 } 50 51 52 } 53 54 @end
KZAppModel.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
KZAppModel.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
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 14 @interface ViewController () <AppViewProtocol> 15 @property (nonatomic,strong)NSArray *apps; 16 @end 17 18 @implementation ViewController 19 20 - (void)viewDidLoad { 21 [super viewDidLoad]; 22 23 //每一行的应用的个数 24 int totalCol = 3; 25 /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/ 26 27 //添加一个小的view 28 CGFloat appW = 80; 29 CGFloat appH = 100; 30 CGFloat marginX = 20; 31 CGFloat marginY = 20; 32 CGFloat hightMargin = 30; 33 CGFloat leftMargin = (self.view.frame.size.width - totalCol * appW - (totalCol - 1) *marginX)* 0.5; 34 35 36 37 for (int i = 0; i < self.apps.count; i++) { 38 39 40 //计算行号和列号 41 int row = i / totalCol; 42 int col = i % totalCol; 43 44 CGFloat appX = leftMargin + (marginX + appW)* col; 45 CGFloat appY = hightMargin + (marginY + appH)* row; 46 47 //1.添加view 48 49 50 //首先拿到一个格子视图 51 // UIView *appView = [[NSBundle mainBundle]loadNibNamed:@"AppView" owner:nil options:nil][0]; 52 53 AppView *appView = [AppView loadNib]; 54 55 56 //1.2设置frame 57 appView.frame = CGRectMake(appX, appY, appW, appH); 58 //1.3设置背景色(便于代码阶段验证,之后会删除) 59 //appView.backgroundColor = [UIColor redColor]; 60 //1.4将这个appView添加到view中 61 [self.view addSubview:appView]; 62 63 //加载数据 64 //NSDictionary *dict = self.apps[i]; 65 //将数据赋值给模型对象 66 KZAppModel *appModel = self.apps[i]; 67 68 69 //通过数组的特性拿到里面的小控件,进行赋值 70 // UIImageView *imageView = (UIImageView *)appView.subviews[0]; 71 // imageView.image = [UIImage imageNamed:appModel.icon]; 72 // 73 // UILabel *label = appView.subviews[1]; 74 // label.text = appModel.name; 75 76 77 appView.appViewModel = appModel; 78 79 80 81 #warning 设置视图的代理为控制器: 82 83 appView.delegate = self; 84 85 86 // UIButton *downBtn = (UIButton *)appView.subviews[2]; 87 // [downBtn addTarget:self action:@selector(btnOnClick:) forControlEvents:UIControlEventTouchUpInside]; 88 89 90 // //2.添加图片UIImageView 91 // CGFloat imageW = 60; 92 // CGFloat imageH = 50; 93 // CGFloat imageX = (appW - imageW)*0.5; 94 // CGFloat imageY = 0; 95 // UIImageView *imageView = [[UIImageView alloc]init]; 96 // imageView.frame = CGRectMake(imageX, imageY, imageW, imageH); 97 // //imageView.backgroundColor = [UIColor blueColor]; 98 // //imageView.image = [UIImage imageNamed:dict[@"icon"]]; 99 // //从模型对象中取出数据 100 // imageView.image = [UIImage imageNamed:appModel.icon]; 101 // [appView addSubview:imageView]; 102 // 103 // 104 // //3.添加应用名称 105 // 106 // CGFloat labelW = 80; 107 // CGFloat labelH = 25; 108 // CGFloat labelX = 0; 109 // CGFloat labelY = imageH; 110 // UILabel *label = [[UILabel alloc]init]; 111 // label.frame = CGRectMake(labelX, labelY, labelW, labelH); 112 // //label.backgroundColor = [UIColor grayColor]; 113 // //label.text = dict[@"name"]; 114 // //从模型对象中取出数据name 115 // label.text = appModel.name; 116 // 117 // //设置字体大小 118 // label.font = [UIFont systemFontOfSize:13]; 119 // //设置字体居中 120 // label.textAlignment = NSTextAlignmentCenter; 121 // [appView addSubview:label]; 122 // 123 // //4.添加下载按钮 124 // 125 // CGFloat downloadW = 60; 126 // CGFloat downloadH = 25; 127 // CGFloat downloadX = 10; 128 // CGFloat downloadY = labelH + labelY; 129 // UIButton *downloadBtn = [[UIButton alloc]init]; 130 // downloadBtn.frame = CGRectMake(downloadX, downloadY, downloadW, downloadH); 131 // //downloadBtn.backgroundColor = [UIColor yellowColor]; 132 // //设置背景图片 133 // [downloadBtn setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal]; 134 // [downloadBtn setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted]; 135 // //设置字体第一种方法 136 // [downloadBtn setTitle:@"下载" forState:UIControlStateNormal]; 137 // 138 // //设置字体第二种方法(不推荐使用) 139 // downloadBtn.titleLabel.text = @"下载"; 140 // 141 // //设置字体大小 142 // downloadBtn.titleLabel.font = [UIFont systemFontOfSize:15]; 143 // [appView addSubview:downloadBtn]; 144 // 145 // 146 // [downloadBtn addTarget:self action:@selector(btnOnClick:) forControlEvents:UIControlEventTouchUpInside]; 147 } 148 149 150 151 152 153 } 154 155 156 157 -(void)appViewDownload:(AppView *)appView{ 158 159 160 161 CGFloat labelW = 120; 162 CGFloat labelH = 30; 163 CGFloat labelX = (self.view.frame.size.width - labelW)* 0.5; 164 CGFloat labelY = (self.view.frame.size.height - labelH)*0.5; 165 UILabel *label = [[UILabel alloc]init]; 166 label.frame = CGRectMake(labelX, labelY, labelW, labelH); 167 label.text = @"正在下载"; 168 //设置字体颜色 169 label.textColor = [UIColor redColor]; 170 //设置字体居中 171 label.textAlignment = NSTextAlignmentCenter; 172 //设置 背景色 173 label.backgroundColor = [UIColor blackColor]; 174 175 //设置圆角的半径 176 label.layer.cornerRadius = 8; 177 //将多余的部分减掉 178 label.layer.masksToBounds = YES; 179 //设置透明度 180 label.alpha = 0.0; 181 //将label添加到view中 182 [self.view addSubview:label]; 183 //使用block动画,动画持续时间2秒 184 [UIView animateWithDuration:2.0 animations:^{ 185 label.alpha = 0.5; 186 } completion:^(BOOL finished) { 187 if (finished) { 188 [UIView animateWithDuration:2.0 delay:0.1 options:UIViewAnimationOptionCurveLinear animations:^{ 189 label.alpha = 0.0; 190 } completion:^(BOOL finished) { 191 //上面将透明度设置为0,界面上已经不显示这个label,但是它仍然在内存中,所以为了节约内存,仍要将其从内存中删除 192 [label removeFromSuperview]; 193 194 }]; 195 } 196 }]; 197 } 198 /** 199 * "懒加载",加载应用数据 200 * 201 */ 202 - (NSArray *)apps{ 203 204 //如果_apps为空,才加载数据 205 if (_apps == nil) { 206 //获取plist的全路径 207 NSString *path = [[NSBundle mainBundle]pathForResource:@"app.plist" ofType:nil]; 208 209 //加载数组 210 NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; 211 212 //创建一个可变数组,来动态接收模型对象 213 NSMutableArray *array = [NSMutableArray array]; 214 215 //通过循环,将字典数组的字典取出,转成模型对象 216 for (NSDictionary *dict in dictArray) { 217 KZAppModel *appModel = [KZAppModel appWithModelDict:dict]; 218 [array addObject:appModel]; 219 } 220 _apps = array; 221 } 222 return _apps; 223 /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/ 224 } 225 226 - (void)didReceiveMemoryWarning { 227 [super didReceiveMemoryWarning]; 228 // Dispose of any resources that can be recreated. 229 } 230 231 @end