IOS第三天

第三天 

******** 九宫格代码的现实
@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 + 1);
    CGFloat marginY = 10;

    for (int i = 0; i < 12; 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(0, 0, kAppViewW, 50)];
//        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(0, CGRectGetMaxY(icon.frame), kAppViewW, 20)];  //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(0, CGRectGetMaxY(lable.frame), kAppViewW, 20)];
        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(80, 400, 160, 40)];
    // 数值是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 + 1);
    CGFloat marginY = 10;

    for (int i = 0; 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[0];
//        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[1];
//        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[2];
//        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(80, 400, 160, 40)];
    // 数值是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(80, 400, 160, 40)];
    // 数值是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(80, 400, 160, 40)];
    // 数值是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

 

posted @ 2015-07-23 11:43  iso  阅读(229)  评论(0编辑  收藏  举报