需求
1.以N宫格的形式展示应用信息
2.APP信息包括图标、名字、下载按钮
3.使用尽可能少的代码,从plist读取app信息,计算每个app图标的位置尺寸信息
 
 
A.思路
1.UI布局:N宫格
2.事件监听
3.动态添加 (by plist)
4.整体封装,组合每个应用信息,使用View的层级包装帮助布局
 
B.实现 (使用纯代码方式)
 
  1 //
2 // ViewController.m
3 // 01-应用管理
4 //
5 // Created by hellovoidworld on 14/11/24.
6 // Copyright (c) 2014年 hellovoidworld. All rights reserved.
7 //
8
9 #import "ViewController.h"
10
11 #define APP_WIDTH 85
12 #define APP_HEIGHT 90
13 #define MARGIN_HEAD 20
14 #define ICON_WIDTH 50
15 #define ICON_HEIGHT 50
16 #define NAME_WIDTH APP_WIDTH
17 #define NAME_HEIGHT 20
18 #define DOWNLOAD_WIDTH (APP_WIDTH - 20)
19 #define DOWNLOAD_HEIGHT 20
20
21 @interface ViewController ()
22
23 /** 存放应用信息 */
24 @property(nonatomic, strong) NSArray *apps; // 应用列表
25
26 @end
27
28 @implementation ViewController
29
30 - (void)viewDidLoad {
31 [super viewDidLoad];
32 // Do any additional setup after loading the view, typically from a nib.
33
34 [self loadApps];
35 }
36
37 - (void)didReceiveMemoryWarning {
38 [super didReceiveMemoryWarning];
39 // Dispose of any resources that can be recreated.
40 }
41
42 #pragma mark 取得应用列表
43 - (NSArray *) apps {
44 if (nil == _apps) {
45 NSString *path = [[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil];
46 _apps = [NSArray arrayWithContentsOfFile:path];
47 }
48
49 return _apps;
50 }
51
52 #pragma mark 加载全部应用列表
53 - (void) loadApps {
54 int appColumnCount = [self appColumnCount];
55 int appRowCount = [self appRowCount];
56
57 CGFloat marginX = (self.view.frame.size.width - APP_WIDTH * appColumnCount) / (appColumnCount + 1);
58 CGFloat marginY = (self.view.frame.size.height - APP_HEIGHT * appRowCount) / (appRowCount + 1) + MARGIN_HEAD;
59
60 int column = 0;
61 int row = 0;
62 for (int index=0; index<self.apps.count; index++) {
63 NSDictionary *appData = self.apps[index];
64
65 // 每个app信息
66 UIView *appView = [[UIView alloc] init];
67
68 CGFloat appX = marginX + column * (marginX + APP_WIDTH);
69 CGFloat appY = marginY + row * (marginY + APP_HEIGHT);
70
71 appView.frame = CGRectMake(appX, appY, APP_WIDTH, APP_HEIGHT);
72
73 // 1.设置APP图片
74 UIImageView *iconView = [[UIImageView alloc] init];
75
76 CGFloat iconMarginX = (appView.frame.size.width - ICON_WIDTH) / 2;
77 CGFloat iconMarginY = 0;
78 iconView.frame = CGRectMake(iconMarginX, iconMarginY, ICON_WIDTH, ICON_HEIGHT);
79
80 iconView.image = [UIImage imageNamed:appData[@"icon"]];
81 [appView addSubview:iconView];
82
83 // 2.设置APP名字
84 UILabel *nameLabel = [[UILabel alloc] init];
85 nameLabel.text = appData[@"name"];
86 CGFloat nameMarginX = (appView.frame.size.width - NAME_WIDTH) / 2;
87 CGFloat nameMarginY = iconMarginY + ICON_HEIGHT;
88 nameLabel.frame = CGRectMake(nameMarginX, nameMarginY, NAME_WIDTH, NAME_HEIGHT);
89 [nameLabel setFont:[UIFont systemFontOfSize:16]];
90 [nameLabel setTextAlignment:NSTextAlignmentCenter];
91 [appView addSubview:nameLabel];
92
93 // 3.设置下载按钮
94 UIButton *downloadButton = [UIButton buttonWithType:UIButtonTypeCustom];
95 CGFloat downloadMarginX = (appView.frame.size.width - DOWNLOAD_WIDTH) / 2;
96 CGFloat downloadMarginY = nameMarginY + NAME_HEIGHT;
97 downloadButton.frame = CGRectMake(downloadMarginX, downloadMarginY, DOWNLOAD_WIDTH, DOWNLOAD_HEIGHT);
98
99 UIImage *downloadNormalImage = [UIImage imageNamed:@"buttongreen"];
100 [downloadButton setBackgroundImage:downloadNormalImage forState:UIControlStateNormal];
101
102 UIImage *downloadHighlightedImage = [UIImage imageNamed:@"buttongreen_highlighted"];
103 [downloadButton setBackgroundImage:downloadHighlightedImage forState:UIControlStateHighlighted];
104
105 [downloadButton setTitle:@"下载" forState:UIControlStateNormal];
106
107 // 不要直接取出titleLabel属性进行操作,因为这样就不能为全部状态进行设置
108 [downloadButton.titleLabel setFont:[UIFont systemFontOfSize:13]];
109
110 [appView addSubview:downloadButton];
111
112
113 [self.view addSubview:appView];
114
115 column++;
116 if (column == appColumnCount) {
117 column = 0;
118 row++;
119 }
120 }
121 }
122
123 #pragma mark 计算列数
124 - (int) appColumnCount {
125 int count = 0;
126 count = self.view.frame.size.width / APP_WIDTH;
127
128 if ((int)self.view.frame.size.width % (int)APP_WIDTH == 0) {
129 count--;
130 }
131
132 return count;
133 }
134
135 #pragma mark 计算行数
136 - (int) appRowCount {
137 int count = 0;
138 count = (self.view.frame.size.height - MARGIN_HEAD) / APP_HEIGHT;
139
140 if ((int)(self.view.frame.size.height - MARGIN_HEAD) % (int)APP_HEIGHT == 0) {
141 count--;
142 }
143
144 return count;
145 }
146 @end
#1. 放入了Images.xcassets中的文件只能通过[UIImage imageNamed:(NSString *) imageName] 访问吗?

[iOS基础控件 - 4.1] APP列表的更多相关文章

  1. [iOS基础控件 - 4.2] APP列表 字典转模型Model

    A.使用字典加载数据的缺点 1.用户自行指定key,容易出错 2.存入.取出都需要key,容易混乱   B.模型 (MVC中的model) 1.字典与模型对比: (1)字典:存储数据,通过字符串类型的 ...

  2. [iOS基础控件 - 4.3] APP列表 xib的使用

    A.storyboard和xib 1.storyboard: 相对xib较重量级,控制整个应用的所有界面 2.xib: 轻量级,一般用来描述局部界面   B.使用 1.新建xib文件 New File ...

  3. [iOS基础控件 - 5.5] 代理设计模式 (基于”APP列表"练习)

    A.概述      在"[iOS基础控件 - 4.4] APP列表 进一步封装,初见MVC模式”上进一步改进,给“下载”按钮加上效果.功能      1.按钮点击后,显示为“已下载”,并且不 ...

  4. [iOS基础控件 - 4.4] 进一步封装"APP列表”,初见MVC模式

    A.从ViewController分离View 之前的代码中,View的数据加载逻辑放在了总的ViewController中,增加了耦合性,应该对控制器ViewController隐藏数据加载到Vie ...

  5. [iOS基础控件 - 6.9.3] QQ好友列表Demo TableView

    A.需求 1.使用plist数据,展示类似QQ好友列表的分组.组内成员显示缩进功能 2.组名使用Header,展示箭头图标.组名.组内人数和上线人数 3.点击组名,伸展.缩回好友组   code so ...

  6. [iOS基础控件 - 6.1] 汽车品牌列表 UITableView多项显示

    A.实现思路 1.拖入UITableView 2.拖曳.连线UITableView控件 3.Controller遵守UITalbeViewDataSource协议 4.设置UITableView的da ...

  7. [iOS基础控件 - 6.11.3] 私人通讯录Demo 控制器的数据传递、存储

    A.需求 1.搭建一个"私人通讯录"Demo 2.模拟登陆界面 账号 密码 记住密码开关 自动登陆开关 登陆按钮 3.退出注销 4.增删改查 5.恢复数据(取消修改)   这个代码 ...

  8. iOS 基础控件(下)

    上篇介绍了UIButton.UILabel.UIImageView和UITextField,这篇就简短一点介绍UIScrollView和UIAlertView. UIScrollView 顾名思义也知 ...

  9. [iOS基础控件 - 5.4] 广告分页代码(UIScrollView制作)

    A.概念 例子就是桌面的APP列表,当APP数量超过一个屏幕,自动进行分页   B.实现思路 1.创建一个UIScrollView,这里设置为宽度跟屏幕相同,高度1/4屏幕高度左右 2.使用代码在UI ...

随机推荐

  1. ASP.NET 访问 MySql

    1. 首先需要安装mysql, 脚本之家下载地址: http://www.jb51.net/softs/2193.html 或者去mysql.com官网都可以,一路next,安装好后,有个简单配置,提 ...

  2. 【BZOJ 1045】 1045: [HAOI2008] 糖果传递

    1045: [HAOI2008] 糖果传递 Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数n& ...

  3. Posix IPC

  4. ajax的GET和POST请求

    GET和POST请求 GET请求时最常见的请求类型,用于向服务器查询信息,必要时可以将查询字符串参数放在URL尾部发送给服务器,如果参数有特殊字符必须正确编码.我们上面使用的例子都是使用GET请求,非 ...

  5. visio2010去除直线交叉处的跨线

    设计(最上方)->连接线(最右侧)->显示跨线(取消打钩)

  6. objective-C 自定义对象归档的实现

    自定义对象要实现归档必须实现NSCoding协议 NSCoding协议有两个方法,encodeWithCoder方法对对象的属性数据做编码处理,initWithCoder解码归档数据来初始化对象. # ...

  7. Git教程(3)命令行使用git简单示例

    基础 Git系统下的的文件有3种状态: 已修改(modified):已修改表示修改了文件,但还没保存到数据库中. 已暂存(staged) : 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下 ...

  8. java参数传递时到底是值传递还是引用传递

    java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...

  9. Android 启动过程总结

    SystemServer的启动 frameworks/base/services/java/com/android/server/SystemServer.java: run() 其中调用Activi ...

  10. @深入注解,在Java中设计和使用自己的注解

    我们用过 JDK给我们提供的  @Override  @Deprecated @SuppressWarning 注解  ,这些注解是JDK给我们提供的 ,我们只是在用别人写好的东西 ,那么我们是否可以 ...