//
// ViewController.m
// 应用管理
#import "ViewController.h"
#import "AppInfo.h"
#import "AppInfoView.h"
@interface ViewController ()
@property (nonatomic,strong) NSArray *appList;
@end
@implementation ViewController
// 懒加载appList
- (NSArray *)appList
{
if (!_appList) {
// 实例化mainBundle
NSBundle *bundle = [NSBundle mainBundle];
// 获取app.plist的路径
NSString *path = [bundle pathForResource:@"app.plist" ofType:nil];
// 从app.plist的路径中获取字典数组
NSArray *array = [NSArray arrayWithContentsOfFile:path];
// 实例化一个可变数组
NSMutableArray *arrayM = [NSMutableArray array];
// 遍历字典数组 将遍历出来的字典转为模型后存放在可变数组中
for (NSDictionary *dict in array) {
[arrayM addObject:[AppInfo appInfoWithDict:dict]];
}
_appList = arrayM;
}
return _appList;
}
- (void)viewDidLoad {
[super viewDidLoad];
// 绘制九宫格
// 总列数为3列
int totalCol = 3;
// view宽度
CGFloat viewW = 80;
// view高度
CGFloat viewH = 90;
// view与view之间的左右间隔 = (整个屏幕的宽度-总列数*view宽度) / (总列数加1)
CGFloat marginX = (self.view.bounds.size.width - totalCol * viewW) / (totalCol + 1);
// view与view之间的上下间隔 = 默认设定为10
CGFloat marginY = 10;
// 开始栏的高度为20(已知,就是电池那栏)
CGFloat startY = 20;
for (int i=0;i<self.appList.count;i++) {
// 当前行数 = 当前标号 / 总列数
int row = i / totalCol;
// 当前列数 = 当前标号 % 总列数
int col = i % totalCol;
// 当前横坐标 = 左右间隔 + (view宽度+左右间隔)* 当前列数
CGFloat x = marginX + (viewW + marginX) * col;
// 当前纵坐标 = 开始栏高度 + 默认的上下间隔 + (view高度+默认上下间隔)* 当前行数
CGFloat y = startY + marginY + (viewH + marginY) * row;
// 实例化一个事先封装好的AppInfoView
AppInfoView *appView = [AppInfoView appInfoViewWithAppInfo:self.appList[i]];
// 将appView放到指定位置绘制九宫格
appView.frame = CGRectMake(x, y, viewW, viewH);
// 将appView加载到主视图中
[self.view addSubview:appView];
}
}
@end
//
// AppInfo.h
// 应用管理
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface AppInfo : NSObject
// 应用程序名称
@property (nonatomic,copy) NSString *name;
// 应用程序图标名称
@property (nonatomic,copy) NSString *icon;
// 图像
// 定义属性时会生成getter&setter方法,还会生成带下划线的成员变量
// 如果是readonly属性 只会生成getter方法,同时没有成员变量
@property (nonatomic,strong,readonly) UIImage *image;
// instancetype 会让编译器检查实例化对象的准确类型
// instancetype 只能用于返回类型,不能当做参数使用
- (instancetype)initWithDict:(NSDictionary *)dict;
/** 工厂方法 */
+ (instancetype)appInfoWithDict:(NSDictionary *)dict;
@end
//
// AppInfo.m
// 应用管理
#import "AppInfo.h"
@interface AppInfo()
{
UIImage *_imageABC;
}
@end
@implementation AppInfo
// 自动返回一个字典的方法
- (instancetype)initWithDict:(NSDictionary *)dict
{
self = [super init];
if (self) {
self.name = dict[@"name"];
self.icon = dict[@"icon"];
}
return self;
}
// 工厂方法
+ (instancetype)appInfoWithDict:(NSDictionary *)dict
{
return [[self alloc]initWithDict:dict];
}
- (UIImage *)image
{
if (!_imageABC) {
_imageABC = [UIImage imageNamed:self.icon];
}
return _imageABC;
}
@end
//
// AppInfoView.h
// 应用管理
#import <UIKit/UIKit.h>
#import "AppInfo.h"
@interface AppInfoView : UIView
+ (instancetype)appInfoView;
+ (instancetype)appInfoViewWithAppInfo:(AppInfo *)appInfo;
@end
//
// AppInfoView.m
// 应用管理
#import "AppInfoView.h"
#import "AppInfo.h"
@interface AppInfoView()
@property (weak, nonatomic) IBOutlet UIImageView *iconImage;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (nonatomic,strong) AppInfo *appInfo;
@end
@implementation AppInfoView
+ (instancetype)appInfoView
{
// 从mainBundle中加载AppinfoView的Xib 返回一个数组
NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"AppinfoView" owner:nil options:nil];
// 返回加载数组中的第一个对象
return [array firstObject];
}
+ (instancetype)appInfoViewWithAppInfo:(AppInfo *)appInfo
{
// 将model中的信息加载到view中
AppInfoView *view = [self appInfoView];
view.appInfo = appInfo;
return view;
}
- (void)setAppInfo:(AppInfo *)appInfo
{
// 在setter方法中千万不要忘记用成员变量记录参数
_appInfo = appInfo;
self.iconImage.image = appInfo.image;
self.nameLabel.text = appInfo.name;
}
- (IBAction)downloadClick
{
// 实例化一个标签
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(80, 400, 160, 40)];
// 设置标签的文字居中
label.textAlignment = NSTextAlignmentCenter;
// 设置标签的背景颜色为亮灰色
label.backgroundColor = [UIColor lightGrayColor];
// 实例化AppInfo = 当前点击按钮对应的appInfo
AppInfo *appInfo = self.appInfo;
// 标签的文字为当前对象下载完成
label.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
// 标签字体大小为系统大小 13.0
label.font = [UIFont systemFontOfSize:13.0];
// 字体透明度为1.0
label.alpha = 1.0;
// 将标签加载到当前视图中
[self.superview addSubview:label];
// 利用block动画完成动画效果 动画时长为2妙 渐变消失 当动画结束之后去掉标签(remove)
[UIView animateWithDuration:2.0 animations:^{
label.alpha = 0.0;
} completion:^(BOOL finished) {
[label removeFromSuperview];
}];
[self.downBtn setTitle:@"下载完成" forState:UIControlStateNormal];
self.downBtn.titleLabel.font = [UIFont systemFontOfSize:10.0];
self.downBtn.enabled = NO;
}
@end