使用 UITableView 创建表格应用演练(3)——使用区段分类显示表格数据

长平狐 发布于 2013/12/26 11:22
阅读 120
收藏 0

上一篇 使用 UITableView 创建表格应用演练(2)——从plist文件加载并显示数据" 完成后,“微博关注人”这个应用虽然距离最终的完成还有不小的距离,但从视觉上已经比演练(1)完成时有了不小的改进。:]

细心的朋友们在上次演练中已经发现,我们定义的数据结构中,有一个名为“类别”的字段,这个字段的设置主要用于帮助我们更好地管理我们的关注对象。本文演练仅仅涉及一个问题,就是如何按照“类别”在表格中分区段显示数据。本此演练之后,相信您会对iOS中的数组(NSMutableArray)和plist文件的使用也会有一个新的理解。

一. 开始之前

开始之前,我们需要简单回顾一下上一次的一些内容,这样便于我们演练的开始。

1. 在FocusUsers.plist文件中顺序存放所有关注用户的数据;

2. 我们定义了一个名为JOYFocusUser的类来存放每个用户的信息;

3. 我们在视图控制器中用到了一个NSMutableArray数组存放plist文件内容,并通过JOYFocusUser类做为映射,便于程序编写过程中的访问。

那么现在问题出来了——从plist文件中加载过来的数据是一个序列的,而分区段显示数据时,单一序列的数组显然有些难以胜任,这个时候我们需要做一个中转。如下图所示:

如果我们从上一讲中的单一序列,变成有图所示的二维序列问题似乎就好解决了。:]

好,思路有了,现在让我们马上动手。

二. 数据调整

1. 在导航区域,点击“FocusUsers.plist”文件,打开我们上次演练中建立的plist文件;

2. 在“FocusUsers.plist”上点击鼠标右键,选择“Open As”“Source Code”,并使用下列代码替换我们上次使用的plist内容:

1 <? xml version="1.0" encoding="UTF-8" ?> 2 <! DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd" > 3 < plist version ="1.0" > 4 < array > 5 < array > 6 < dict > 7 < key >UserName </ key > 8 < string >爱Apps </ string > 9 < key >Image </ key > 10 < string >爱Apps.jpeg </ string > 11 < key >WebSite </ key > 12 < string >http://weibo.com/iapps </ string > 13 < key >Favorite </ key > 14 < real >3.5 </ real > 15 < key >Category </ key > 16 < string >苹果咨询 </ string > 17 </ dict > 18 < dict > 19 < key >UserName </ key > 20 < string >苹果汇 </ string > 21 < key >Image </ key > 22 < string >苹果汇.jpeg </ string > 23 < key >WebSite </ key > 24 < string >http://weibo.com/appleus </ string > 25 < key >Favorite </ key > 26 < real >3.5 </ real > 27 < key >Category </ key > 28 < string >苹果咨询 </ string > 29 </ dict > 30 < dict > 31 < key >UserName </ key > 32 < string >数码iPhone大百科 </ string > 33 < key >Image </ key > 34 < string >数码iPhone大百科.jpeg </ string > 35 < key >WebSite </ key > 36 < string >http://weibo.com/gx110 </ string > 37 < key >Favorite </ key > 38 < real >3.5 </ real > 39 < key >Category </ key > 40 < string >苹果咨询 </ string > 41 </ dict > 42 </ array > 43 < array > 44 < dict > 45 < key >UserName </ key > 46 < string >新浪视野 </ string > 47 < key >Image </ key > 48 < string >新浪视野.jpeg </ string > 49 < key >WebSite </ key > 50 < string >http://weibo.com/wboard </ string > 51 < key >Favorite </ key > 52 < real >3.5 </ real > 53 < key >Category </ key > 54 < string >官方机构 </ string > 55 </ dict > 56 </ array > 57 < array > 58 < dict > 59 < key >UserName </ key > 60 < string >李开复 </ string > 61 < key >Image </ key > 62 < string >李开复.jpeg </ string > 63 < key >WebSite </ key > 64 < string >http://weibo.com/kaifulee </ string > 65 < key >Favorite </ key > 66 < real >3.5 </ real > 67 < key >Category </ key > 68 < string >IT名人 </ string > 69 </ dict > 70 </ array > 71 </ array > 72 </ plist >

对比上一次演练中我们使用的plist文件,我们多引入了一层array定义,这样就把原有的一维数据序列,调整成二维序列了。怎么样?还不错吧。:]

三. 数据加载处理

1. 在导航区域,点击打开“JOYTableViewController.m”文件;

2. 在接口定义中将原来定义的数据名称由_userList改为_categoryList,如下所示:

1 @interface JOYTableViewController () { 2 @private 3 NSMutableArray * _categoryList; 4 }

3. 在viewDidLoad方法中调整数据加载部分进行调整,调整后的viewDidLoad方法如下所示:

1 - ( void )viewDidLoad 2 { 3 [super viewDidLoad]; 4 5 // 设定pList文件路径 6 NSString *dataPath = [[NSBundle mainBundle]pathForResource: @" FocusUsers.plist " ofType:nil]; 7 // 填充数组内容 8 NSMutableArray *array = [NSMutableArray arrayWithContentsOfFile:dataPath]; 9 10 _categoryList = [[NSMutableArray alloc]init]; 11 for (NSDictionary *item in array) { 12 NSMutableArray *userList = [[NSMutableArray alloc]init]; 13 14 // 针对每个分类项,创建一个用户数组 15 for (NSDictionary *users in item) { 16 JOYFocusUser *user = [[JOYFocusUser alloc]initWithItem:users]; 17 [userList addObject:user]; 18 } 19 20 // 将用户数组项目添加到分类数组中 21 [_categoryList addObject:userList]; 22 } 23 }

4. 找到numberOfSectionsInTableView方法,将其中代码进行修改,如下所示:

1 - (NSInteger)numberOfSectionsInTableView:(UITableView * )tableView 2 { 3 return [_categoryList count]; 4 }

在本演练数据中,我们一共包含三个分类,所以在此返回结果是3。

5. 找到

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

方法,将其中代码进行修改,如下所示:

1 - (NSInteger)tableView:(UITableView * )tableView numberOfRowsInSection:(NSInteger)section 2 { 3 return [[_categoryList objectAtIndex:section]count]; 4 }

这里的代码稍微有些别扭,我们会在后续调整一下,让它更好读一些,在此先简单解释一下。

从plist文件的结构中,我们不难发现[_categoryList objectAtIndex:section]对应的是指定区段数的一个用户数组,假如我们把这个理解为“userList”,则这条语句可以看成是return [userList count],返回的是指定区段的用户数组的个数。

6. 找到

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

方法,将其中解析数据部分代码进行修改,修改后的方法如下所示:

1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath * )indexPath 2 { 3 static NSString *CellIdentifier = @" Cell " ; 4 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 5 6 // Configure the cell... 7 // 实例化单元格对象 8 if (cell == nil) { 9 cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 10 } 11 12 NSMutableArray *array = [_categoryList objectAtIndex:[indexPath section]]; 13 JOYFocusUser *user = [array objectAtIndex:[indexPath row]]; 14 15 // 设置单元格文本 16 // NSDictionary *item = [_userList objectAtIndex:indexPath.row]; 17 [cell.textLabel setText:[user userName]]; 18 // 设定字体 19 [cell.textLabel setFont:[UIFont fontWithName: @" Helvetica " size: 16.0f ]]; 20 // 改变字体颜色 21 [cell.textLabel setTextColor:[UIColor orangeColor]]; 22 // 调整文本居中对齐 23 [cell.textLabel setTextAlignment:UITextAlignmentCenter]; 24 25 // 显示头像 26 [cell.imageView setImage:[user image]]; 27 28 return cell; 29 }

为了便于大家的阅读,我把上一次演练中的代码注释了,这样方便我们更加直观地看出到底做了哪些修改。

7. 运行一下,看看效果:]

天啊,忙乎了一溜够,竟然和上次演练之后没有发生任何的变化,这⋯⋯

不要着急,现在激动人心的时刻就要到了,嘿嘿。

8. 找到numberOfSectionsInTableView方法,在它的下面插入一个

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 方法

并增加一条语句,如下所示:

1 - (NSString *)tableView:(UITableView * )tableView titleForHeaderInSection:(NSInteger)section { 2 // 获取指定区段的用户数组 3 NSMutableArray *userList = [_categoryList objectAtIndex:section]; 4 // 获取数组中第一个用户记录 5 JOYFocusUser *user = [userList objectAtIndex: 0 ]; 6 // 返回该用户的分类名称 7 return user.categoryName; 8 }

相关语句到底干了什么,见注释即可,我就不再啰嗦了。

9. 运行一下,如下图所示:

哈哈,怎么样?不复杂吧。

小提示:可能有不少从其他平台,例如Eclipse或者MS VS等转过来的朋友会向我当初一样有一些类似的疑问:这个方法是怎么加入的呢?我怎么知道系统预设了这个方法呢?有没有某个菜单命令能够弹出一个对话框,让我选择具体要重载哪个方法呢?

答案是直接输入。呵呵,刚开始使用Xcode时,我也有些不习惯,不过后来发现,Xcode提供的智能输入提示非常友好,在程序开发时非常高效地,程序员不用时不时地因为一些小事,就不得不把手从键盘移到鼠标上,去做一些无聊的事情。在Xcode中,编写某一个类的代码时,几乎可以不用使用鼠标,就完成所有的编码工作。

好了,言归正传,在上述的代码中,某些地方有些取巧,如果你只是开发这么一个简单的应用,已经足够了。不过如果考虑到以后系统的维护和扩充,我们还是要尽量将数据和界面分开。

四. 使用分类数据模型

1. 在导航区域,点击并打开“JOYFocusUser.h”文件,在文件末尾增加如下代码:

1 @interface JOYCategory : NSObject 2 3 @property (strong, nonatomic) NSString * categoryName; 4 @property (strong, nonatomic) NSMutableArray * userList; 5 6 // 使用用户列表实例化对象 7 - ( id)initWithArray:(NSMutableArray * )userList; 8 9 @end

在此,我们新定义了一个JOYCategory的类,用于按类别存储用户列表;

2. 点击打开“JOYFocusUser.m”文件,在文件的末尾增加如下代码:

1 @implementation JOYCategory 2 @synthesize categoryName = _categoryName; 3 @synthesize userList = _userList; 4 5 - ( id)initWithArray:(NSMutableArray * )userList { 6 7 self = [super init]; 8 if (self) { 9 NSMutableArray *list = [[NSMutableArray alloc]init]; 10 for (NSDictionary *item in userList) { 11 JOYFocusUser *user = [[JOYFocusUser alloc]initWithItem:item]; 12 [list addObject:user]; 13 } 14 15 JOYFocusUser *user = [list objectAtIndex: 0 ]; 16 _categoryName = user.categoryName; 17 _userList = list; 18 } 19 return self; 20 } 21 22 @end

3. 在导航区域,点击打开“JOYTableViewController.m”文件;

4. 对viewDidLoad中的数据加载部分的代码调整如下:

1 - ( void )viewDidLoad 2 { 3 [super viewDidLoad]; 4 5 // 设定pList文件路径 6 NSString *dataPath = [[NSBundle mainBundle]pathForResource: @" FocusUsers.plist " ofType:nil]; 7 // 填充数组内容 8 NSMutableArray *array = [NSMutableArray arrayWithContentsOfFile:dataPath]; 9 10 _categoryList = [[NSMutableArray alloc]init]; 11 // for (NSDictionary *item in array) { 12 // NSMutableArray *userList = [[NSMutableArray alloc]init]; 13 // 14 // // 针对每个分类项,创建一个用户数组 15 // for (NSDictionary *users in item) { 16 // JOYFocusUser *user = [[JOYFocusUser alloc]initWithItem:users]; 17 // [userList addObject:user]; 18 // } 19 // 20 // // 将用户数组项目添加到分类数组中 21 // [_categoryList addObject:userList]; 22 // } 23 for (NSMutableArray *item in array) { 24 JOYCategory *category = [[JOYCategory alloc]initWithArray:item]; 25 [_categoryList addObject:category]; 26 } 27 }

5. 在 

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section方法中做如下调整:

1 - (NSString *)tableView:(UITableView * )tableView titleForHeaderInSection:(NSInteger)section { 2 // // 获取指定区段的用户数组 3 // NSMutableArray *userList = [_categoryList objectAtIndex:section]; 4 // // 获取数组中第一个用户记录 5 // JOYFocusUser *user = [userList objectAtIndex:0]; 6 // // 返回该用户的分类名称 7 // return user.categoryName; 8 JOYCategory *category = [_categoryList objectAtIndex:section]; 9 return [category categoryName]; 10 }

6. 在

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section方法中做如下调整:

1 - (NSInteger)tableView:(UITableView * )tableView numberOfRowsInSection:(NSInteger)section 2 { 3 // return [[_categoryList objectAtIndex:section]count]; 4 JOYCategory *category = [_categoryList objectAtIndex:section]; 5 return [category.userList count]; 6 }

7. 在

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法中做如下调整:

1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath * )indexPath 2 { 3 static NSString *CellIdentifier = @" Cell " ; 4 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 5 6 // Configure the cell... 7 // 实例化单元格对象 8 if (cell == nil) { 9 cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 10 } 11 12 // NSMutableArray *array = [_categoryList objectAtIndex:[indexPath section]]; 13 // JOYFocusUser *user = [array objectAtIndex:[indexPath row]]; 14 JOYCategory *category = [_categoryList objectAtIndex:[indexPath section]]; 15 JOYFocusUser *user = [category.userList objectAtIndex:[indexPath row]]; 16 17 // 设置单元格文本 18 // NSDictionary *item = [_userList objectAtIndex:indexPath.row]; 19 [cell.textLabel setText:[user userName]]; 20 // 设定字体 21 [cell.textLabel setFont:[UIFont fontWithName: @" Helvetica " size: 16.0f ]]; 22 // 改变字体颜色 23 [cell.textLabel setTextColor:[UIColor orangeColor]]; 24 // 调整文本居中对齐 25 [cell.textLabel setTextAlignment:UITextAlignmentCenter]; 26 27 // 显示头像 28 [cell.imageView setImage:[user image]]; 29 30 return cell; 31 }

小提示:为了便于大家的阅读,我把前面演练中的代码注释了,这样方便我们更加直观地看出到底做了哪些修改。由于我把每一个方法的完成代码都复制过来了,其实我们在每个方法中所作的修改只是一两条语句而已。

8. 运行看一下效果,和前面演练完的效果并没有太大的变化,不过现在的代码的可读性已经有所提高了:]

五. 小结

首先要向大家表示歉意,因为本人的博客只是利用业余时间编写的,更新速度有些缓慢,还望大家见谅。

本演练源程序下载地址:JoyiOSMyFocus3.zip

到目前位置,我们对UITableView的数据加载、显示、分组已经做了一个初步的介绍。在后面的演练中,我们将针对自定义单元格、表格数据操作以及自定义视图进行介绍,同时引入一个iOS应用中非常常见的Navigation控件。计划还需要两~三章的内容可以完成,敬请期待。


原文链接:http://www.cnblogs.com/liufan9/archive/2012/06/10/2542153.html
加载中
返回顶部
顶部