使用 UITableView 創建表格應用演練(3)——使用區段分類顯示表格數據


上一篇 使用 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控件。計划還需要兩~三章的內容可以完成,敬請期待。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM