ios教程(4)--九宫格布局实现一个小案例

实现效果


1.开发前的思路

1> mainBundle中加载Plist

2> 按照plist中的数据数量先确定各个appView的大小和位置

3> 使用代码创建appView中的子控件,并显示内容

代码一

//
//  ViewController.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/3.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
/**
 *  数据plist
 */
@property (nonatomic,strong) NSArray *appInfo;
@end

@implementation ViewController

- (NSArray *)appInfo
{
    if (_appInfo == nil) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
        _appInfo = [NSArray arrayWithContentsOfFile:path];
    }
    return _appInfo;
}

- (void)viewDidLoad {
    [super viewDidLoad];
#define totaCol 3
#define padding 20
    
    CGFloat viewW = 80;
    CGFloat viewH = 90;
    CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
    CGFloat marginY = 20;

    
    for (int i = 0; i < self.appInfo.count; i++) {
        int  row = i / totaCol;
        int col = i % totaCol;
        CGFloat x = marginX + (viewW + marginX) * col;
        CGFloat y = marginY + (viewH + marginY) * row + padding;
        
        // 读取数组中的字典
        NSDictionary *dict = self.appInfo[i];
        
        UIView *appView =  [[UIView alloc] init];
        appView.frame = CGRectMake(x, y, viewW, viewH);
        [self.view addSubview:appView];
        //设置图标
        UIImageView *imageView = [[UIImageView alloc] init];
        imageView.frame = CGRectMake(0, 0, viewW, 50);
        //设置图片
        imageView.image = [UIImage imageNamed:dict[@"icon"]];
        //按照比例显示图像
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        [appView addSubview:imageView];
        //设置lable
        UILabel *label = [[UILabel alloc] init];
        label.frame = CGRectMake(0, imageView.bounds.size.height, viewW, 20);
        //设置文字内容
        label.text = dict[@"name"];
        //设置文字大小
        label.font = [UIFont systemFontOfSize:12];
        //设置文字居中对齐
        label.textAlignment = NSTextAlignmentCenter;
        [appView addSubview:label];
        //设置button
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(15, 70, viewW - 30, 20);
        //设置文字
        /**
         不能使用下载的方法
         *   button.titleLabel.text = @"下载";
         应该使用下面的方法
          [button setTitle:@"下载" forState:UIControlStateNormal];
         */
       
        [button setTitle:@"下载" forState:UIControlStateNormal];
        //设置文字大小
        //@property中readonly表示不允许修改对象的指针地址,但是可以修改对象的属性
        button.titleLabel.font = [UIFont systemFontOfSize:12];
        //设置按钮图片
        [button setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];
        [button setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted];
        [appView addSubview:button];
        button.tag = i;
        [button addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];
    
    }
}

- (void)downloadClick:(UIButton *)button
{
    NSLog(@" %ld ",(long)button.tag);
    //提示用户已经完成
    UILabel *lable = [[UILabel alloc] init];
    lable.frame = CGRectMake(80, self.view.bounds.size.height - 100, 200, 40);
    lable.textAlignment = NSTextAlignmentCenter;
    lable.backgroundColor = [UIColor lightGrayColor];
    NSDictionary *dict = self.appInfo[button.tag];
    lable.text = [NSString stringWithFormat:@"下载%@完成",dict[@"name"]];
    lable.alpha = 1.0;
    lable.font = [UIFont systemFontOfSize:13];
    
    //动画效果
    //动画效果完成之后,将lable从视图中删除
    //首尾式动画,只能做动画,要处理完成后的操作不方便
//    [UIView beginAnimations:nil context:nil];
//    [UIView setAnimationDuration:1.0];
//    lable.alpha = 1.0;
//    [UIView commitAnimations];
    
    /**
     *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
     *  在ios中基本使用首尾式动画
     */
    [UIView animateWithDuration:1.0 animations:^{
        lable.alpha = 0.0;
    } completion:^(BOOL finished) {
        //删除lable
        [lable removeFromSuperview];
    }];
    
    button.enabled = NO;
    
    [self.view addSubview:lable];
    
}

关于上面方法的总结

2. 关于九宫格布局的计算方法

========================================

关于如何计算界面的九宫格布局,其实可以有若干种方法,不必死记课堂的代码,

要能够顺利计算出每一个小格子准确的坐标,建议:

1先创建若干小的视图

2找到自己理解比较容易的计算方法

3编写循环创建九宫格布局


要求:能够公用的常量尽量给抽取出来,以便增加九宫格布局的灵活性,尽量保证做到:

1> 根据要显示的数据自动调整小格子的位置和数量

2> 一旦调整了要显示的列数,仅需要修改少量的数值即可做到


3. 关于UIButton的一些补充

========================================

3.1 按钮的类型

iOS的控件中,只有UIButton提供了类方法,可以在实例化按钮时指定按钮的不同类型。


UIButtonTypeCustom[[UIButton alloc] init]是等价的


3.2 修改按钮字体


UIButton中定义有两个readonly的属性:

1> titleLabel

2> imageView

@propertyreadonly表示不允许修改这两个属性的指针地址,但是可以修改其属性


注意:由于按钮的字体大小是所有状态共用的,因此可以通过

button.titleLabel.font= [UIFont systemFontOfSize:14.0];

修改按钮标签文本的字体大小


但是不能使用以下代码设置按钮标签的文本内容

button.titleLabel.text = @"下载";


因为按钮标签的文本内容是跟按钮的状态向关的


4. 块动画

========================================

4.1 首尾式动画


如果只是修改控件的属性,使用首尾式动画还是比较方便的,但是如果需要在动画完成后做后续处理,就不是那么方便了


[UIView beginAnimations:nil context:nil];

[UIView setAnimationDuration:1.0];

// 修改属性的动画代码

// ......

[UIView commitAnimations];


4.2 块动画


块动画相对来说比较灵活,尤为重要的是能够将动画相关的代码编写在一起,便于代码的阅读和理解


[UIView animateWithDuration:2.0 animations:^{

    // 修改控件属性动画

    label.alpha = 0.0;

} completion:^(BOOL finished) {

    // 删除控件

    [label removeFromSuperview];

}];

代码优化一

    - (NSArray *)appInfo
    {
        if (_appInfo == nil) {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
            NSArray *array = [NSArray arrayWithContentsOfFile:path];
            //将数值转换成模型,意味着self.applist中存储的是SDAppLIst
            //1. 遍历数组,将数组中的字典依次转换成SDApplist对象,添加到一个临时数组
            //2. self.SDApplist = 临时数组
            NSMutableArray *arrayM = [NSMutableArray array];
            for (NSDictionary *dict in array) {
                SDApplist *appInfo = [[SDApplist alloc] init];
                appInfo.name = dict[@"name"];
                appInfo.icon = dict[@"icon"];
                [arrayM addObject:appInfo];
            }
            _appInfo = arrayM;
        }
        return _appInfo;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
#define totaCol 3
#define padding 20
        
        CGFloat viewW = 80;
        CGFloat viewH = 90;
        CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
        CGFloat marginY = 20;
        
        
        for (int i = 0; i < self.appInfo.count; i++) {
            int  row = i / totaCol;
            int col = i % totaCol;
            CGFloat x = marginX + (viewW + marginX) * col;
            CGFloat y = marginY + (viewH + marginY) * row + padding;
            
            // 读取数组中的字典
            SDApplist *appInfo = self.appInfo[i];
            
            UIView *appView =  [[UIView alloc] init];
            appView.frame = CGRectMake(x, y, viewW, viewH);
            [self.view addSubview:appView];
            //设置图标
            UIImageView *imageView = [[UIImageView alloc] init];
            imageView.frame = CGRectMake(0, 0, viewW, 50);
            //设置图片
            imageView.image = [UIImage imageNamed:appInfo.icon];
            //按照比例显示图像
            imageView.contentMode = UIViewContentModeScaleAspectFit;
            [appView addSubview:imageView];
            //设置lable
            UILabel *label = [[UILabel alloc] init];
            label.frame = CGRectMake(0, imageView.bounds.size.height, viewW, 20);
            //设置文字内容
            label.text = appInfo.name;
            //设置文字大小
            label.font = [UIFont systemFontOfSize:12];
            //设置文字居中对齐
            label.textAlignment = NSTextAlignmentCenter;
            [appView addSubview:label];
            //设置button
            UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
            button.frame = CGRectMake(15, 70, viewW - 30, 20);
            //设置文字
            /**
             不能使用下载的方法
             *   button.titleLabel.text = @"下载";
             应该使用下面的方法
             [button setTitle:@"下载" forState:UIControlStateNormal];
             */
            
            [button setTitle:@"下载" forState:UIControlStateNormal];
            //设置文字大小
            //@property中readonly表示不允许修改对象的指针地址,但是可以修改对象的属性
            button.titleLabel.font = [UIFont systemFontOfSize:12];
            //设置按钮图片
            [button setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];
            [button setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted];
            [appView addSubview:button];
            button.tag = i;
            [button addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];
            
        }
    }
    
    - (void)downloadClick:(UIButton *)button
    {
        NSLog(@" %ld ",(long)button.tag);
        //提示用户已经完成
        UILabel *lable = [[UILabel alloc] init];
        lable.frame = CGRectMake(80, self.view.bounds.size.height - 100, 200, 40);
        lable.textAlignment = NSTextAlignmentCenter;
        lable.backgroundColor = [UIColor lightGrayColor];
        SDApplist *appInfo = self.appInfo[button.tag];
        lable.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
        lable.alpha = 1.0;
        lable.font = [UIFont systemFontOfSize:13];
        
        //动画效果
        //动画效果完成之后,将lable从视图中删除
        //首尾式动画,只能做动画,要处理完成后的操作不方便
        //    [UIView beginAnimations:nil context:nil];
        //    [UIView setAnimationDuration:1.0];
        //    lable.alpha = 1.0;
        //    [UIView commitAnimations];
        
        /**
         *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
         *  在ios中基本使用首尾式动画
         */
        [UIView animateWithDuration:1.0 animations:^{
            lable.alpha = 0.0;
        } completion:^(BOOL finished) {
            //删除lable
            [lable removeFromSuperview];
        }];
        
        button.enabled = NO;
        
        [self.view addSubview:lable];
        
    }

SDApplist

//
//  SDApplist.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SDApplist : NSObject
/**
 *  名字
 */
@property (nonatomic, strong)NSString *name;
/**
 *  图片
 */
@property (nonatomic, strong)NSString *icon;
@end



代码优化2

//
//  ViewController.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/3.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "ViewController.h"
#include "SDApplist.h"

@interface ViewController ()
/**
 *  数据plist
 */
@property (nonatomic,strong) NSArray *appInfo;
@end

@implementation ViewController

- (NSArray *)appInfo
{
    if (_appInfo == nil) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
        NSArray *array = [NSArray arrayWithContentsOfFile:path];
        //将数值转换成模型,意味着self.applist中存储的是SDAppLIst
        NSMutableArray *arrayM = [NSMutableArray array];
        for (NSDictionary *dict in array) {
            SDApplist *appInfo = [SDApplist SDApplistWithDict:dict];
            [arrayM addObject:appInfo];
        }
        _appInfo = arrayM;
    }
    return _appInfo;
}

- (void)viewDidLoad {
    [super viewDidLoad];
#define totaCol 3
#define padding 20
    
    CGFloat viewW = 80;
    CGFloat viewH = 90;
    CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
    CGFloat marginY = 20;

    
    for (int i = 0; i < self.appInfo.count; i++) {
        int  row = i / totaCol;
        int col = i % totaCol;
        CGFloat x = marginX + (viewW + marginX) * col;
        CGFloat y = marginY + (viewH + marginY) * row + padding;
        
        // 读取数组中的字典
        SDApplist *appInfo = self.appInfo[i];
        
        UIView *appView =  [[UIView alloc] init];
        appView.frame = CGRectMake(x, y, viewW, viewH);
        [self.view addSubview:appView];
        //设置图标
        UIImageView *imageView = [[UIImageView alloc] init];
        imageView.frame = CGRectMake(0, 0, viewW, 50);
        //设置图片
//        imageView.image = appInfo.image;
        imageView.image = appInfo.image;
        //按照比例显示图像
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        [appView addSubview:imageView];
        //设置lable
        UILabel *label = [[UILabel alloc] init];
        label.frame = CGRectMake(0, imageView.bounds.size.height, viewW, 20);
        //设置文字内容
        label.text = appInfo.name;
        //设置文字大小
        label.font = [UIFont systemFontOfSize:12];
        //设置文字居中对齐
        label.textAlignment = NSTextAlignmentCenter;
        [appView addSubview:label];
        //设置button
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(15, 70, viewW - 30, 20);
        //设置文字
        /**
         不能使用下载的方法
         *   button.titleLabel.text = @"下载";
         应该使用下面的方法
          [button setTitle:@"下载" forState:UIControlStateNormal];
         */
       
        [button setTitle:@"下载" forState:UIControlStateNormal];
        //设置文字大小
        //@property中readonly表示不允许修改对象的指针地址,但是可以修改对象的属性
        button.titleLabel.font = [UIFont systemFontOfSize:12];
        //设置按钮图片
        [button setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];
        [button setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted];
        [appView addSubview:button];
        button.tag = i;
        [button addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];
    
    }
}

- (void)downloadClick:(UIButton *)button
{
    NSLog(@" %ld ",(long)button.tag);
    //提示用户已经完成
    UILabel *lable = [[UILabel alloc] init];
    lable.frame = CGRectMake(80, self.view.bounds.size.height - 100, 200, 40);
    lable.textAlignment = NSTextAlignmentCenter;
    lable.backgroundColor = [UIColor lightGrayColor];
    SDApplist *appInfo = self.appInfo[button.tag];
    lable.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
    lable.alpha = 1.0;
    lable.font = [UIFont systemFontOfSize:13];
    
    //动画效果
    //动画效果完成之后,将lable从视图中删除
    //首尾式动画,只能做动画,要处理完成后的操作不方便
//    [UIView beginAnimations:nil context:nil];
//    [UIView setAnimationDuration:1.0];
//    lable.alpha = 1.0;
//    [UIView commitAnimations];
    
    /**
     *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
     *  在ios中基本使用首尾式动画
     */
    [UIView animateWithDuration:1.0 animations:^{
        lable.alpha = 0.0;
    } completion:^(BOOL finished) {
        //删除lable
        [lable removeFromSuperview];
    }];
    
    button.enabled = NO;
    
    [self.view addSubview:lable];
    
}
@end

SDApplist.h

//
//  SDApplist.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SDApplist : NSObject
/**
 *  名字
 */
@property (nonatomic, strong)NSString *name;
/**
 *  图片
 */
@property (nonatomic, strong)NSString *icon;
/**
 *  自定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量
 *  如果是readonly属性,只会生成getter方法,同事没有成员变量
 */
@property (nonatomic,readonly ,strong)UIImage *image;

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict;

@end


SDApplist.m

//
//  SDApplist.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "SDApplist.h"
#import <UIKit/UIKit.h>

@interface SDApplist()
{
    UIImage *_imageA;
}

@end

@implementation SDApplist


- (instancetype)initWithDict:(NSDictionary *)dict
{
    self = [super init];
    if (self) {
        self.name = dict[@"name"];
        self.icon = dict[@"icon"];
    }
    return self;
}

- (UIImage *)image
{
    if (_imageA == NULL) {
        _imageA = [UIImage imageNamed:self.icon];
    }
    return _imageA;
}

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}


@end

5. 字典转模型

========================================

5.1 字典转模型的好处:

1> 降低代码的耦合度

2> 所有字典转模型部分的代码统一集中在一处处理,降低代码出错的几率

3> 在程序中直接使用模型的属性操作,提高编码效率


模型应该提供一个可以传入字典参数的构造方法

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)xxxWithDict:(NSDictionary *)dict;


5.2 instancetype &id

1> instancetype在类型表示上,跟id一样,可以表示任何对象类型

2> instancetype只能用在返回值类型上,不能像id一样用在参数类型上

3> instancetypeid多一个好处:编译器会检测instancetype的真实类型


5.3 在模型中添加readonly属性

// 定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量

// 而如果是readonly属性,则只会生成getter方法,同时没有成员变量

@property (nonatomic,strong,readonly) UIImage *image;


@interface LFAppInfo()

{

    UIImage *_imageABC;

}

- (UIImage *)image

{

    if (!_imageABC) {

        _imageABC = [UIImage imageNamed:self.icon];

    }

    return _imageABC;

}

在模型中合理地使用只读属性,可以进一步降低代码的耦合度。


5.4 使用数据模型的好处:

*** 调用方不用关心模型内部的任何处理细节!


代码优化三

    //
    //  ViewController.m
    //  01-应用程序管理
    //
    //  Created by sunda on 15/7/3.
    //  Copyright (c) 2015年 sunda. All rights reserved.
    //
    
#import "ViewController.h"
#include "SDApplist.h"
#include "SDAPPlnfoView.h"
    
    @interface ViewController ()
    /**
     *  数据plist
     */
    @property (nonatomic,strong) NSArray *appInfo;
    @end
    
    @implementation ViewController
    
    - (NSArray *)appInfo
    {
        if (_appInfo == nil) {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
            NSArray *array = [NSArray arrayWithContentsOfFile:path];
            //将数值转换成模型,意味着self.applist中存储的是SDAppLIst
            NSMutableArray *arrayM = [NSMutableArray array];
            for (NSDictionary *dict in array) {
                SDApplist *appInfo = [SDApplist SDApplistWithDict:dict];
                [arrayM addObject:appInfo];
            }
            _appInfo = arrayM;
        }
        return _appInfo;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
#define totaCol 3
#define padding 20
        
        CGFloat viewW = 80;
        CGFloat viewH = 90;
        CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
        CGFloat marginY = 20;
        
        
        for (int i = 0; i < self.appInfo.count; i++) {
            int  row = i / totaCol;
            int col = i % totaCol;
            CGFloat x = marginX + (viewW + marginX) * col;
            CGFloat y = marginY + (viewH + marginY) * row + padding;
            
            // 读取数组中的字典
            SDApplist *appInfo = self.appInfo[i];
            
            //loadNibNamed 会将名为AppInfoView中定义的使用视图全部加载出来,并且按照XIB中自定义的顺序,返回一个视图的数组
            NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"APPInfo" owner:nil options:nil];
            NSLog(@"%@",array);
            SDAPPlnfoView *appView = [array firstObject];
            appView.frame = CGRectMake(x, y, viewW, viewH);
            [self.view addSubview:appView];
            //1、设置图片
            appView.iconImage.image = appInfo.image;
            //2、设置文本
            appView.nameLable.text = appInfo.name;
            //3、设置button的tag
            appView.dowBtn.tag = i;
            //4、设置button的监听方法
            [appView.dowBtn addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];
            
        }
    }
    
    - (void)downloadClick:(UIButton *)button
    {
        NSLog(@" %ld ",(long)button.tag);
        //提示用户已经完成
        UILabel *lable = [[UILabel alloc] init];
        lable.frame = CGRectMake(80, self.view.bounds.size.height - 100, 200, 40);
        lable.textAlignment = NSTextAlignmentCenter;
        lable.backgroundColor = [UIColor lightGrayColor];
        SDApplist *appInfo = self.appInfo[button.tag];
        lable.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
        lable.alpha = 1.0;
        lable.font = [UIFont systemFontOfSize:13];
        
        //动画效果
        //动画效果完成之后,将lable从视图中删除
        //首尾式动画,只能做动画,要处理完成后的操作不方便
        //    [UIView beginAnimations:nil context:nil];
        //    [UIView setAnimationDuration:1.0];
        //    lable.alpha = 1.0;
        //    [UIView commitAnimations];
        
        /**
         *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
         *  在ios中基本使用首尾式动画
         */
        [UIView animateWithDuration:1.0 animations:^{
            lable.alpha = 0.0;
        } completion:^(BOOL finished) {
            //删除lable
            [lable removeFromSuperview];
        }];
        
        button.enabled = NO;
        
        [self.view addSubview:lable];
        
    }
}


//
//  SDApplist.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SDApplist : NSObject
/**
 *  名字
 */
@property (nonatomic, strong)NSString *name;
/**
 *  图片
 */
@property (nonatomic, strong)NSString *icon;
/**
 *  自定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量
 *  如果是readonly属性,只会生成getter方法,同事没有成员变量
 */
@property (nonatomic,readonly ,strong)UIImage *image;

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict;

@end

//
//  SDApplist.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "SDApplist.h"
#import <UIKit/UIKit.h>

@interface SDApplist()
{
    UIImage *_imageA;
}

@end

@implementation SDApplist


- (instancetype)initWithDict:(NSDictionary *)dict
{
    self = [super init];
    if (self) {
        self.name = dict[@"name"];
        self.icon = dict[@"icon"];
    }
    return self;
}

- (UIImage *)image
{
    if (_imageA == NULL) {
        _imageA = [UIImage imageNamed:self.icon];
    }
    return _imageA;
}

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}


@end

//
 //  SDAPPlnfoView.h
 //  01-应用程序管理
 //
 //  Created by sunda on 15/7/13.
 //  Copyright (c) 2015年 sunda. All rights reserved.
 //
 
 #import <UIKit/UIKit.h>

 @interface SDAPPlnfoView : UIView
 
 
//  下载按钮
@property (weak, nonatomic) IBOutlet UIButton *dowBtn;
 

//图片
@property (strong, nonatomic) IBOutlet UIImageView *iconImage;

//文本
@property (strong, nonatomic) IBOutlet UILabel *nameLable;

代码优化四

    //
    //  ViewController.m
    //  01-应用程序管理
    //
    //  Created by sunda on 15/7/3.
    //  Copyright (c) 2015年 sunda. All rights reserved.
    //
    
#import "ViewController.h"
#include "SDApplist.h"
#include "SDAPPlnfoView.h"
    
    @interface ViewController ()
    /**
     *  数据plist
     */
    @property (nonatomic,strong) NSArray *appInfo;
    @end
    
    @implementation ViewController
    
    - (NSArray *)appInfo
    {
        if (_appInfo == nil) {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
            NSArray *array = [NSArray arrayWithContentsOfFile:path];
            //将数值转换成模型,意味着self.applist中存储的是SDAppLIst
            NSMutableArray *arrayM = [NSMutableArray array];
            for (NSDictionary *dict in array) {
                SDApplist *appInfo = [SDApplist SDApplistWithDict:dict];
                [arrayM addObject:appInfo];
            }
            _appInfo = arrayM;
        }
        return _appInfo;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
#define totaCol 3
#define padding 20
        
        CGFloat viewW = 80;
        CGFloat viewH = 90;
        CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
        CGFloat marginY = 20;
        
        
        for (int i = 0; i < self.appInfo.count; i++) {
            int  row = i / totaCol;
            int col = i % totaCol;
            CGFloat x = marginX + (viewW + marginX) * col;
            CGFloat y = marginY + (viewH + marginY) * row + padding;
            
            // 读取数组中的字典
            SDApplist *appInfo = self.appInfo[i];
            
            //loadNibNamed 会将名为AppInfoView中定义的使用视图全部加载出来,并且按照XIB中自定义的顺序,返回一个视图的数组
            NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"APPInfo" owner:nil options:nil];
            NSLog(@"%@",array);
            SDAPPlnfoView *appView = [array firstObject];
            appView.frame = CGRectMake(x, y, viewW, viewH);
            [self.view addSubview:appView];
            //读取数组中的AppInfo
            appView.appInfo = self.appInfo[i];
            
            
            
            appView.dowBtn.tag = i;
            //4、设置button的监听方法
            [appView.dowBtn addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];
            
        }
    }
    
    - (void)downloadClick:(UIButton *)button
    {
        NSLog(@" %ld ",(long)button.tag);
        //提示用户已经完成
        UILabel *lable = [[UILabel alloc] init];
        lable.frame = CGRectMake(80, self.view.bounds.size.height - 100, 200, 40);
        lable.textAlignment = NSTextAlignmentCenter;
        lable.backgroundColor = [UIColor lightGrayColor];
        SDApplist *appInfo = self.appInfo[button.tag];
        lable.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
        lable.alpha = 1.0;
        lable.font = [UIFont systemFontOfSize:13];
        
        //动画效果
        //动画效果完成之后,将lable从视图中删除
        //首尾式动画,只能做动画,要处理完成后的操作不方便
        //    [UIView beginAnimations:nil context:nil];
        //    [UIView setAnimationDuration:1.0];
        //    lable.alpha = 1.0;
        //    [UIView commitAnimations];
        
        /**
         *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
         *  在ios中基本使用首尾式动画
         */
        [UIView animateWithDuration:1.0 animations:^{
            lable.alpha = 0.0;
        } completion:^(BOOL finished) {
            //删除lable
            [lable removeFromSuperview];
        }];
        
        button.enabled = NO;
        
        [self.view addSubview:lable];
        
    }
}
//
//  SDApplist.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SDApplist : NSObject
/**
 *  名字
 */
@property (nonatomic, strong)NSString *name;
/**
 *  图片
 */
@property (nonatomic, strong)NSString *icon;
/**
 *  自定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量
 *  如果是readonly属性,只会生成getter方法,同事没有成员变量
 */
@property (nonatomic,readonly ,strong)UIImage *image;

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict;

@end


//
//  SDApplist.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "SDApplist.h"
#import <UIKit/UIKit.h>

@interface SDApplist()
{
    UIImage *_imageA;
}

@end

@implementation SDApplist


- (instancetype)initWithDict:(NSDictionary *)dict
{
    self = [super init];
    if (self) {
        self.name = dict[@"name"];
        self.icon = dict[@"icon"];
    }
    return self;
}

- (UIImage *)image
{
    if (_imageA == NULL) {
        _imageA = [UIImage imageNamed:self.icon];
    }
    return _imageA;
}

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}


@end

  SDAPPlnfoView.h
  01-应用程序管理

  Created by sunda on 15/7/13.
  Copyright (c) 2015年 sunda. All rights reserved.


#import <UIKit/UIKit.h>
@class SDApplist;
@interface SDAPPlnfoView : UIView


//下载按钮

@property (weak, nonatomic) IBOutlet UIButton *dowBtn;

@property (strong, nonatomic) SDApplist *appInfo;
@end

    //
    //  SDAPPlnfoView.m
    //  01-应用程序管理
    //
    //  Created by sunda on 15/7/13.
    //  Copyright (c) 2015年 sunda. All rights reserved.
    //
    
#import "SDAPPlnfoView.h"
#import "SDApplist.h"
    @interface SDAPPlnfoView()
    /**
     *  图片
     */
    @property (strong, nonatomic) IBOutlet UIImageView *iconImage;
    /**
     *  文本
     */
    @property (strong, nonatomic) IBOutlet UILabel *nameLable;
    
    @end
    
    @implementation SDAPPlnfoView
    
    - (void)setAppInfo:(SDApplist *)appInfo
    {
        //在Settrt中一定要用成员变量记录参数
        _appInfo = appInfo;
        self.iconImage.image = appInfo.image;
        self.nameLable.text = appInfo.name;
    }

最后一次优化

//
//  ViewController.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/3.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "ViewController.h"
#include "SDApplist.h"
#include "SDAPPlnfoView.h"

@interface ViewController ()
/**
 *  数据plist
 */
@property (nonatomic,strong) NSArray *appInfo;
@end

@implementation ViewController

- (NSArray *)appInfo
{
    if (_appInfo == nil) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
        NSArray *array = [NSArray arrayWithContentsOfFile:path];
        //将数值转换成模型,意味着self.applist中存储的是SDAppLIst
        NSMutableArray *arrayM = [NSMutableArray array];
        for (NSDictionary *dict in array) {
            SDApplist *appInfo = [SDApplist SDApplistWithDict:dict];
            [arrayM addObject:appInfo];
        }
        _appInfo = arrayM;
    }
    return _appInfo;
}

- (void)viewDidLoad {
    [super viewDidLoad];
#define totaCol 3
#define padding 20
    
    CGFloat viewW = 80;
    CGFloat viewH = 90;
    CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
    CGFloat marginY = 20;

    
    for (int i = 0; i < self.appInfo.count; i++) {
        int  row = i / totaCol;
        int col = i % totaCol;
        CGFloat x = marginX + (viewW + marginX) * col;
        CGFloat y = marginY + (viewH + marginY) * row + padding;
    
    
        SDAPPlnfoView *appView = [SDAPPlnfoView appInfoViewWithAppList:self.appInfo[i]];
        appView.frame = CGRectMake(x, y, viewW, viewH);
        [self.view addSubview:appView];

    }
}
@end


//
//  SDApplist.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SDApplist : NSObject
/**
 *  名字
 */
@property (nonatomic, strong)NSString *name;
/**
 *  图片
 */
@property (nonatomic, strong)NSString *icon;
/**
 *  自定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量
 *  如果是readonly属性,只会生成getter方法,同事没有成员变量
 */
@property (nonatomic,readonly ,strong)UIImage *image;

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict;

@end

//
//  SDApplist.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "SDApplist.h"
#import <UIKit/UIKit.h>

@interface SDApplist()
{
    UIImage *_imageA;
}

@end

@implementation SDApplist


- (instancetype)initWithDict:(NSDictionary *)dict
{
    self = [super init];
    if (self) {
        self.name = dict[@"name"];
        self.icon = dict[@"icon"];
    }
    return self;
}

- (UIImage *)image
{
    if (_imageA == NULL) {
        _imageA = [UIImage imageNamed:self.icon];
    }
    return _imageA;
}

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}


@end

//
//  SDAPPlnfoView.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/13.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <UIKit/UIKit.h>
@class SDApplist;
@interface SDAPPlnfoView : UIView


+(instancetype)appInfoView;
+(instancetype)appInfoViewWithAppList:(SDApplist *)applist;

@end
//
//  SDAPPlnfoView.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/13.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "SDAPPlnfoView.h"
#import "SDApplist.h"
@interface SDAPPlnfoView()
/**
 *  图片
 */
@property (strong, nonatomic) IBOutlet UIImageView *iconImage;
/**
 *  文本
 */
@property (strong, nonatomic) IBOutlet UILabel *nameLable;

/**
 *  下载按钮
 */
@property (weak, nonatomic) IBOutlet UIButton *dowBtn;

@property (strong, nonatomic) SDApplist *appInfo;

@end

@implementation SDAPPlnfoView

- (void)setAppInfo:(SDApplist *)appInfo
{
    //在Settrt中一定要用成员变量记录参数
    _appInfo = appInfo;
    self.iconImage.image = appInfo.image;
    self.nameLable.text = appInfo.name;
}
- (IBAction)downloadClick:(UIButton *)button{
    //提示用户已经完成
    UILabel *lable = [[UILabel alloc] init];
    lable.frame = CGRectMake(80, 500 , 200, 40);
    lable.textAlignment = NSTextAlignmentCenter;
    lable.backgroundColor = [UIColor lightGrayColor];
    
    SDApplist *appInfo = self.appInfo;
    lable.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
    lable.alpha = 1.0;
    lable.font = [UIFont systemFontOfSize:13];
    
    //动画效果
    //动画效果完成之后,将lable从视图中删除
    //首尾式动画,只能做动画,要处理完成后的操作不方便
    //    [UIView beginAnimations:nil context:nil];
    //    [UIView setAnimationDuration:1.0];
    //    lable.alpha = 1.0;
    //    [UIView commitAnimations];
    
    /**
     *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
     *  在ios中基本使用首尾式动画
     */
    [UIView animateWithDuration:1.0 animations:^{
        lable.alpha = 0.0;
    } completion:^(BOOL finished) {
        //删除lable
        [lable removeFromSuperview];
    }];
    
    button.enabled = NO;
    
    [self.superview addSubview:lable];

}
+ (instancetype)appInfoView
{
    //loadNibNamed 会将名为AppInfoView中定义的使用视图全部加载出来,并且按照XIB中自定义的顺序,返回一个视图的数组
        NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"APPInfo" owner:nil options:nil];

        return [array firstObject];
}
+ (instancetype)appInfoViewWithAppList:(SDApplist *)applist
{
    SDAPPlnfoView *view = [self appInfoView];
    view.appInfo = applist;
    return view;
}



@end


6. XIB

========================================

Xib文件可以用来描述某一块局部的UI界面


XIB & Storyboard

相同点:

1都用来描述软件界面

2都用Interface Builder工具来编辑

不同点

1>  Xib是轻量级的,用来描述局部的UI界面

2>  Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系


7. View的封装思路

========================================

1如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部子控件的创建屏蔽起来,不让外界关心

2外界可以传入对应的模型数据给viewview拿到模型数据后给内部的子控件设置对应的数据



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值