第三天

******** 九宫格代码的现实
@interface HMViewController ()
/** 应用程序列表 */
@property (nonatomic, strong) NSArray *appList;
@end @implementation HMViewController - (NSArray *)appList
{
if (_appList == nil) {
// appList保存的是字典=>模型
// _appList = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil]];
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil]]; // 创建一个临时数组 字典转模型
NSMutableArray *arraM = [NSMutableArray array]; //把NSArray 转NSMutableArray
// 遍历数组,依次转换模型
for (NSDictionary *dict in array) {
HMAppInfo *appInfo = [[HMAppInfo alloc] init];
appInfo.name = dict[@"name"];
appInfo.icon = dict[@"icon"]; [arraM addObject:appInfo];
} // 将临时数组为属性赋值
_appList = arraM;
}
return _appList;
} - (void)viewDidLoad
{
[super viewDidLoad]; // 搭建界面,九宫格
#define kAppViewW 80
#define kAppViewH 90
#define kColCount 3
#define kStartY 20 // 320 - 3 * 80 = 80 / 4 = 20
CGFloat marginX = (self.view.bounds.size.width - kColCount * kAppViewW) / (kColCount + );
CGFloat marginY = ; for (int i = ; i < ; i++) {
// 行
// 0, 1, 2 => 0
// 3, 4, 5 => 1
int row = i / kColCount; // 列
// 0, 3, 6 => 0
// 1, 4, 7 => 1
// 2, 5, 8 => 2
int col = i % kColCount; CGFloat x = marginX + col * (marginX + kAppViewW);
CGFloat y = kStartY + marginY + row * (marginY + kAppViewH); UIView *appView = [[UIView alloc] initWithFrame:CGRectMake(x, y, kAppViewW, kAppViewH)];
// appView.backgroundColor = [UIColor redColor];
[self.view addSubview:appView]; // 实现视图内部细节
// NSDictionary *dict = self.appList[i];
HMAppInfo *appInfo = self.appList[i]; // 1> UIImageView
UIImageView *icon = [[UIImageView alloc] initWithFrame:CGRectMake(, , kAppViewW, )];
// icon.backgroundColor = [UIColor greenColor]; // 设置图像
//icon.image = [UIImage imageNamed:dict[@"icon"]];
icon.image = [UIImage imageNamed:appInfo.icon];// // 设置图像填充模式,等比例显示(CTRL+6)
icon.contentMode = UIViewContentModeScaleAspectFit; [appView addSubview:icon]; // 2> UILabel -> 应用程序名称
// CGRectGetMaxY(frame) = frame.origin.y + frame.size.height
UILabel *lable = [[UILabel alloc] initWithFrame:CGRectMake(, CGRectGetMaxY(icon.frame), kAppViewW, )]; //icon.frame icon的y的组大值
// lable.backgroundColor = [UIColor blueColor]; // 设置应用程序名称
// lable.text = dict[@"name"];
lable.text = appInfo.name; // 设置字体
lable.font = [UIFont systemFontOfSize:13.0];
lable.textAlignment = NSTextAlignmentCenter; [appView addSubview:lable]; // 3> UIButton -> 下载按钮
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(, CGRectGetMaxY(lable.frame), kAppViewW, )];
button.backgroundColor = [UIColor yellowColor]; // 背景图片
[button setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted]; // 按钮都是有状态的,不同状态可以对应不同的标题
[button setTitle:@"下载" forState:UIControlStateNormal];
// *** 一定不要使用以下方法,修改按钮标题
// button.titleLabel.text = @"aaa"; // 修改字体(titleLabel是只读的)
// readonly表示不允许修改titleLabel的指针,但是可以修改label的字体
// 提示:按钮的字体是不区分状态的!
button.titleLabel.font = [UIFont systemFontOfSize:12.0]; [appView addSubview:button];
}
}
@end
********模型的优化
- (NSArray *)appList
{
if (_appList == nil) {
// appList保存的是字典=>模型
// _appList = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil]];
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil]]; // 创建一个临时数组
NSMutableArray *arraM = [NSMutableArray array];
// 遍历数组,依次转换模型
for (NSDictionary *dict in array) { // 类方法可以快速实例化一个对象
// HMAppInfo *appInfo = [[HMAppInfo alloc] initWithDict:dict]; HMAppInfo *appInfo = [HMAppInfo appInfoWithDict:dict]; // NSString *str = [HMAppInfo appInfoWithDict:dict];
// NSLog(@"%d", str.length); [arraM addObject:appInfo];
} // 将临时数组为属性赋值
_appList = arraM;
}
return _appList;
} @implementation HMAppInfo
- (instancetype)initWithDict:(NSDictionary *)dict
{
// self 是 对象
self = [super init];
if (self) {
// 用字典给属性赋值,所有与plist键值有关的方法,均在此处!
self.name = dict[@"name"];
self.icon = dict[@"icon"];
}
return self;
} + (instancetype)appInfoWithDict:(NSDictionary *)dict
{
// self 是 class
return [[self alloc] initWithDict:dict];
} @end
//接口
@interface HMAppInfo : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *icon; /**
instancetype 主要用于在类方法实例化对象时,让编译器主动推断对象的实际类型 以避免使用id,会造成开发中不必要的麻烦,减少出错几率! instancetype是苹果在iOS7才开始主推的 C++11 auto
在swift语言中,绝大多数类的实例化,都不需要再指定类型 instancetype只能用于返回值使用!!!不能当做参数使用
*/ /** 通常在写模型的实例化方法时,以下两个方法,都需要实现 */
/** 使用字典实例化模型 */
- (instancetype)initWithDict:(NSDictionary *)dict;
/** 类方法可以快速实例化一个对象 */
+ (instancetype)appInfoWithDict:(NSDictionary *)dict; @end
******* 模型的封装KVC的使用

@implementation HMAppInfo
// 合成指令,主动指定属性使用的成员变量名称
@synthesize image = _image; /**
使用KVC的注意事项 1> plist中的键值名称必须与模型中的属性一致
2> 模型中的属性可以不全部出现在plist中
*/
- (UIImage *)image
{
if (_image == nil) {
_image = [UIImage imageNamed:self.icon];
}
return _image;
} - (instancetype)initWithDict:(NSDictionary *)dict
{
// self 是 对象
self = [super init];
if (self) {
// 用字典给属性赋值,所有与plist键值有关的方法,均在此处!
// self.name = dict[@"name"];
// self.icon = dict[@"icon"]; // KVC - key value coding键值编码
// 是一种间接修改/读取对象属性的一种方法
// KVC 被称为 cocoa 的大招!
// 参数:
// 1. 数值
// 2. 属性名称
// [self setValue:dict[@"name"] forKeyPath:@"name"];
// [self setValue:dict[@"icon"] forKeyPath:@"icon"];
// setValuesForKeysWithDictionary本质上就是调用以上两句代码
[self setValuesForKeysWithDictionary:dict];
}
return self;
} + (instancetype)appInfoWithDict:(NSDictionary *)dict
{
// self 是 class
return [[self alloc] initWithDict:dict];
} + (NSArray *)appList
{
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil]]; // 创建一个临时数组
NSMutableArray *arrayM = [NSMutableArray array]; // 遍历数组,依次转换模型
for (NSDictionary *dict in array) {
[arrayM addObject:[HMAppInfo appInfoWithDict:dict]];
} return arrayM;
} @end
*******按钮的操作
*******按钮的操作
按钮的事件
[button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside]; /** 按钮监听方法 */
- (void)click:(UIButton *)button
{
NSLog(@"%s %d", __func__, button.tag); // 取出appInfo
HMAppInfo *appInfo = self.appList[button.tag]; // 添加一个UILabel到界面上
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
// 数值是0表示黑色,1表示纯白
// alpha表示透明度
label.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.2]; label.text = appInfo.name;
label.textAlignment = NSTextAlignmentCenter; [self.view addSubview:label];
// 动画效果
// 收尾式动画,修改对象的属性,frame,bounds,alpha
// 初始透明度,完全透明
label.alpha = 0.0; // 禁用按钮
button.enabled = NO; // 动画结束之后删除
// ^ 表示是block,块代码,是一个预先准备好的代码块,可以当做参数传递,在需要的时候执行!
// 块代码在OC中,使用的非常普遍!
[UIView animateWithDuration:1.0f animations:^{
NSLog(@"动画开始");
// 要修改的动画属性
label.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
label.alpha = 0.0;
} completion:^(BOOL finished) {
// 动画完成后,所做的操作
NSLog(@"动画完成"); // button.enabled = NO; [label removeFromSuperview];
}];
}]; NSLog(@"-------"); // 收尾式动画,不容易监听动画完成时间,而且不容易实现动画嵌套
// [UIView beginAnimations:nil context:nil];
// [UIView setAnimationDuration:1.0f];
// label.alpha = 1.0;
// [UIView commitAnimations];
}

***********XIB优化九宫格

***********XIB优化九宫格
#import "HMViewController.h"
#import "HMAppInfo.h" #define kAppViewW 80
#define kAppViewH 90
#define kColCount 3
#define kStartY 20 @interface HMViewController ()
/** 应用程序列表 */
@property (nonatomic, strong) NSArray *appList;
@end @implementation HMViewController - (NSArray *)appList
{
if (_appList == nil) {
_appList = [HMAppInfo appList];
}
return _appList;
} - (void)viewDidLoad
{
[super viewDidLoad]; // XIB的测试代码
// 加载XIB,XIB中可以包含多个自定义视图,通常只保存一个
// UIView *view = [[[NSBundle mainBundle] loadNibNamed:@"HMAppView" owner:nil options:nil] lastObject]; // 搭建界面,九宫格
// 320 - 3 * 80 = 80 / 4 = 20
CGFloat marginX = (self.view.bounds.size.width - kColCount * kAppViewW) / (kColCount + );
CGFloat marginY = ; for (int i = ; i < self.appList.count; i++) {
// 行
// 0, 1, 2 => 0
// 3, 4, 5 => 1
int row = i / kColCount; // 列
// 0, 3, 6 => 0
// 1, 4, 7 => 1
// 2, 5, 8 => 2
int col = i % kColCount; CGFloat x = marginX + col * (marginX + kAppViewW);
CGFloat y = kStartY + marginY + row * (marginY + kAppViewH); // 从XIB来加载自定义视图
UIView *appView = [[[NSBundle mainBundle] loadNibNamed:@"HMAppView" owner:nil options:nil] lastObject];
// 设置视图位置
appView.frame = CGRectMake(x, y, kAppViewW, kAppViewH); // UIView *appView = [[UIView alloc] initWithFrame:CGRectMake(x, y, kAppViewW, kAppViewH)];
[self.view addSubview:appView]; // 实现视图内部细节
HMAppInfo *appInfo = self.appList[i]; // 1> UIImageView
UIImageView *icon = appView.subviews[];
// UIImageView *icon = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kAppViewW, 50)]; // 设置图像
icon.image = appInfo.image; // 设置图像填充模式,等比例显示(CTRL+6)
// icon.contentMode = UIViewContentModeScaleAspectFit; // [appView addSubview:icon]; // 2> UILabel -> 应用程序名称
UILabel *label = appView.subviews[];
// UILabel *lable = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(icon.frame), kAppViewW, 20)]; // 设置应用程序名称
label.text = appInfo.name; // 设置字体
// label.font = [UIFont systemFontOfSize:13.0];
// label.textAlignment = NSTextAlignmentCenter; // [appView addSubview:label]; // 3> UIButton -> 下载按钮
UIButton *button = appView.subviews[];
// UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(label.frame), kAppViewW, 20)]; // 背景图片
// [button setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];
// [button setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted]; // 按钮都是有状态的,不同状态可以对应不同的标题
// [button setTitle:@"下载" forState:UIControlStateNormal];
// *** 一定不要使用以下方法,修改按钮标题
// button.titleLabel.text = @"aaa"; // 修改字体(titleLabel是只读的)
// readonly表示不允许修改titleLabel的指针,但是可以修改label的字体
// 提示:按钮的字体是不区分状态的!
// button.titleLabel.font = [UIFont systemFontOfSize:12.0]; // [appView addSubview:button]; // 给按钮添加监听方法
button.tag = i; [button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
}
} /** 按钮监听方法 */
- (void)click:(UIButton *)button
{
NSLog(@"%s %d", __func__, button.tag); // 取出appInfo
HMAppInfo *appInfo = self.appList[button.tag]; // 添加一个UILabel到界面上
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
// 数值是0表示黑色,1表示纯白
// alpha表示透明度
label.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.2]; label.text = appInfo.name;
label.textAlignment = NSTextAlignmentCenter; [self.view addSubview:label];
// 动画效果
// 收尾式动画,修改对象的属性,frame,bounds,alpha
// 初始透明度,完全透明
label.alpha = 0.0; // 禁用按钮
button.enabled = NO; // 动画结束之后删除
// ^ 表示是block,块代码,是一个预先准备好的代码块,可以当做参数传递,在需要的时候执行!
// 块代码在OC中,使用的非常普遍!
[UIView animateWithDuration:1.0f animations:^{
NSLog(@"动画开始");
// 要修改的动画属性
label.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
label.alpha = 0.0;
} completion:^(BOOL finished) {
// 动画完成后,所做的操作
NSLog(@"动画完成"); // button.enabled = NO; [label removeFromSuperview];
}];
}]; NSLog(@"-------"); // 收尾式动画,不容易监听动画完成时间,而且不容易实现动画嵌套
// [UIView beginAnimations:nil context:nil];
// [UIView setAnimationDuration:1.0f];
// label.alpha = 1.0;
// [UIView commitAnimations];
} @end
***********模型显示视图
***********模型显示视图
// 从XIB来加载自定义视图
HMAppView *appView = [[[NSBundle mainBundle] loadNibNamed:@"HMAppView" owner:nil options:nil] lastObject]; #import "HMAppView.h"
#import "HMAppInfo.h" @interface HMAppView()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *label;
@end @implementation HMAppView /**
利用setter方法设置视图的界面显示
*/
- (void)setAppInfo:(HMAppInfo *)appInfo
{
_appInfo = appInfo; self.label.text = appInfo.name;
self.iconView.image = appInfo.image;
} /** 按钮监听方法 */
- (IBAction)click:(UIButton *)button
{
// NSLog(@"%s %d", __func__, button.tag);
//
// // 取出appInfo
// HMAppInfo *appInfo = self.appList[button.tag]; // 添加一个UILabel到界面上
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
// 数值是0表示黑色,1表示纯白
// alpha表示透明度
label.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.2]; label.text = self.appInfo.name;
label.textAlignment = NSTextAlignmentCenter; // self.superview就是视图控制器中的self.view
[self.superview addSubview:label];
// 动画效果
// 收尾式动画,修改对象的属性,frame,bounds,alpha
// 初始透明度,完全透明
label.alpha = 0.0; // 禁用按钮
button.enabled = NO; // 动画结束之后删除
// ^ 表示是block,块代码,是一个预先准备好的代码块,可以当做参数传递,在需要的时候执行!
// 块代码在OC中,使用的非常普遍!
[UIView animateWithDuration:1.0f animations:^{
NSLog(@"动画开始");
// 要修改的动画属性
label.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
label.alpha = 0.0;
} completion:^(BOOL finished) {
// 动画完成后,所做的操作
NSLog(@"动画完成"); [label removeFromSuperview];
}];
}];
} @end
******************以上的代码的优化
HMAppView *appView = [HMAppView appViewWithAppInfo:self.appList[i]]; #import "HMAppView.h"
#import "HMAppInfo.h" @interface HMAppView()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *label;
@end @implementation HMAppView + (instancetype)appView
{
return [[[NSBundle mainBundle] loadNibNamed:@"HMAppView" owner:nil options:nil] lastObject];
} + (instancetype)appViewWithAppInfo:(HMAppInfo *)appInfo
{
// 1. 实例化一个视图
HMAppView *view = [self appView]; // 2. 设置视图的显示
view.appInfo = appInfo; // 3. 返回视图
return view;
} /**
利用setter方法设置视图的界面显示
*/
- (void)setAppInfo:(HMAppInfo *)appInfo
{
_appInfo = appInfo; self.label.text = appInfo.name;
self.iconView.image = appInfo.image;
} /** 按钮监听方法 */
- (IBAction)click:(UIButton *)button
{
// NSLog(@"%s %d", __func__, button.tag);
//
// // 取出appInfo
// HMAppInfo *appInfo = self.appList[button.tag]; // 添加一个UILabel到界面上
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
// 数值是0表示黑色,1表示纯白
// alpha表示透明度
label.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.2]; label.text = self.appInfo.name;
label.textAlignment = NSTextAlignmentCenter; // self.superview就是视图控制器中的self.view
[self.superview addSubview:label];
// 动画效果
// 收尾式动画,修改对象的属性,frame,bounds,alpha
// 初始透明度,完全透明
label.alpha = 0.0; // 禁用按钮
button.enabled = NO; // 动画结束之后删除
// ^ 表示是block,块代码,是一个预先准备好的代码块,可以当做参数传递,在需要的时候执行!
// 块代码在OC中,使用的非常普遍!
[UIView animateWithDuration:1.0f animations:^{
NSLog(@"动画开始");
// 要修改的动画属性
label.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
label.alpha = 0.0;
} completion:^(BOOL finished) {
// 动画完成后,所做的操作
NSLog(@"动画完成"); [label removeFromSuperview];
}];
}];
} @end
05-07 15:43