实现效果
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
@property中readonly表示不允许修改这两个属性的指针地址,但是可以修改其属性
注意:由于按钮的字体大小是所有状态共用的,因此可以通过
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> instancetype比id多一个好处:编译器会检测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> 外界可以传入对应的模型数据给view,view拿到模型数据后给内部的子控件设置对应的数据