随着学习的深入,涉及到的知识点也越来越多,需要理解和学习的新知识也随之增加。在完成这个应用管理的时,花了不少时间,也遇到了不少问题。通过字典初始化模型对象的方式、创建模型对象、xib文件的使用等等,都是新的知识。但我觉得,只要肯花心思和下功夫去学习,那么它将不会是问题。虽然没有完成最后的功能,但也基本完成了基本界面的搭建。
一、功能分析
(1)以九宫格的形式展示应用信息。
(2)点击下载按钮后,做出相应的操作。
二、步骤分析
(1)加载应用信息。
(2)根据应用的个数创建对应的view。
(3)监听下载按钮的点击。
三、九宫格行号和列好的算法分析
(1)每一行的y轴一样,行号决定y的值。计算行号:row = index / totalColumns.
(2)每一列的x轴一样,列好决定x的值。计算列好:col = index % totalColumns.
(3)九宫格之间间隙的计算。间隙 = (控制器view的宽度 - totalColumns * 应用的宽度)/ (totalColumns+1)
CGFloat marginX = (self.view.frame.size.width - totalColumns * appW)/(totalColumns+1);
CGFloat marginY = 15;
(4)应用所在x轴和y轴的计算。相信大家都比较好理解这个,这里就不多说明了,只要画一个图出来,就可以了。
//3.3 设置frame
<span style="white-space:pre"> </span>int row = index/totalColumns;
int col = index%totalColumns;
// 计算APP所在的x和y
CGFloat appX = marginX + col * (appW + marginX);
CGFloat appY = 30 + row * (appH + marginY);
(5)说明:之所以把totalColumns,独立出来定义一个变量,是因为在后期要进行维护修改的时候,比较方便。若要更改列数,只需要更改totalColumns的值即可。算式里面的值不用去更改。
四、字典转模型的简单介绍
(1)模型类:只要是继承自NSObject的类就是一个模型类。用来存放数据的类,也就是实现对数据的封装。
(2)字典转模型示意图:
(3)字典转模型的好处:
① 降低代码的耦合度。
② 所有字典转模型部分的代码统一集中在一处处理,降低代码出错的几率。
③ 在程序中直接使用模型的属性操作,提高编码的效率。‘
④ 调用方不用关心模型内部的任何处理细节,从而实现了对数据的封装,让外部无法知识具体的数据的定义。
五、xib文件的介绍和使用
描述软件界面,属于轻量级的,一般用来描述局部界面。
在应用管理-九宫格这个项目中,主要用到了,UIView、UIImageView、UILabel以及UIButton。整体效果如下图。
需要注意的地方:
(1)在属性设置一栏,将Size设置为Freeform,只有设置为Freeform,UIView的尺寸才能被我们所修改。第三个Status Bar 是状态栏,这里我们选择None,因为如果不设置成None,则会出现电量的状态栏。其余4个,可动可不动。
(2)在尺寸一栏,我们将UIView的Width和Height分别设置为85*90.
(3)在Identity 一栏,将class设置为KIMAppView。也就是对应于继承自UIView的类。并将.m文件中的iconView属性和那么Label属性与xib中的UIImageView和UILabel进行连线,让KIMAppView控制使用xib文件。
六、运行截图
因为还没有实现监听下载按钮,所以运行结果只有如下图所示的界面了。监听那一块,会在往后的学习中,进行完善。
七、源代码
由于整个项目的代码比较多,所以只贴一部分相对比较重要的出来。
(1)在ViewController.m文件中。这块代码,主要是计算每个应用的Width和Height,计算该应用在view中的x轴和y轴,以及计算每个应用之间的间隙的计算。最后就是循环创建appview,并且将appview添加到view中。
<span style="color:#ff6600;">- (void)viewDidLoad {
[super viewDidLoad];
// 添加应用信息
// 1. 总列数(一行最多3列)
int totalColumns = 3;
// 1. 应用图标的尺寸
CGFloat appW = 85;
CGFloat appH = 90;
// 2. 间隙 = (控制器view的宽度-3*应用宽度)/4
CGFloat marginX = (self.view.frame.size.width - totalColumns * appW)/(totalColumns+1);
CGFloat marginY = 15;
// 3. 根据应用个数创建对应的应用框(index 0 ~ 11)
for(int index = 0;index < self.apps.count;index++){
//3.1 创建view
KIMAppView *appView = [KIMAppView appViewWithApp:self.apps[index]];
//3.2 添加view
[self.view addSubview:appView];
//3.3 设置frame
int row = index/totalColumns;
int col = index%totalColumns;
// 计算APP所在的x和y
CGFloat appX = marginX + col * (appW + marginX);
CGFloat appY = 30 + row * (appH + marginY);
appView.frame = CGRectMake(appX, appY, appW, appH);
}
}</span>
用读取plist文件中的内容,将其内容加载的模型数组中。再遍历数组,创建对应的模型对象,最后将模型对象添加到数组中,并且为_apps赋值后返回_apps。
<span style="font-size:14px;color:#ff6600;">-(NSArray *)apps{
// 初始化
if(_apps == nil){
//1. 获得plist文件的全路径
NSString *path = [[NSBundle mainBundle]pathForResource:@"app.plist" ofType:nil];
//2. 加载数据,从路径中加载数据
NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
//3. 将dictArray里面的所有字典转成模型对象,放到新的数组中
NSMutableArray *appArray = [NSMutableArray array];
// 遍历数组
for(NSDictionary *dict in dictArray){
//3.1 创建模型对象
KIMApp *app = [KIMApp appWithDict:dict];
//3.2 添加模型对象到数组中
[appArray addObject:app];
}
//4. 赋值
_apps = appArray;
}
return _apps;
}</span>
八、总结
学习iOS也有一段时间了, 一步步走来,看着学习的知识越来越多,敲的代码越来越长时,我想自己的能力也得到了不少的提升。在应用管理的这个项目中,主要是学习封装的思想,在完成项目时,尽量将成员变量和属性封装在一个模型类中,在模型类中提供方法,以供外界访问,但外界并不能直接访问其成员变量和属性,从而实现封装。其次就是学习xib文件的使用,xib文件在我们描述局部界面的时,是不可或缺的。最后就是巩固对之前NSBundle和plist文件的学习。
——爱分享,一起学,共成长。