上一篇 使用UITableView創建表格應用演練(1) 介紹了一個非常簡單的表格加載和顯示的演練。有的朋友可能會說,這也說的忒簡單了,能不能來點復雜的?
別着急,做為程序員,要記住:無論多么復雜的應用都是由簡單的應用演化而成的。
本文目標
本文以上一篇為基礎,對應用進行擴展,介紹以下內容:
1. 數據結構定義;
2. 從plist文件加載並顯示數據;
3. 在表格中顯示頭像並調整表格樣式;
4. 使用數據模型。
一. 數據結構定義
在上一篇演練中,使用NSArray定義了一個數組提供表格內容,但是在實際應用中,這種功能遠遠不能滿足實際使用需求。
前文中,我們提到要做一個維護“微博關注人”的應用。那么對於關注人,一個名字顯然不能滿足我們應用的需求。
在開始之前,我們不妨先花點時間,確定一下除了姓名之外,我們還對哪些信息感興趣,從而確定一下數據結構。見下圖:
我們給關注對象增加五個屬性:姓名、頭像、網址、喜好程度和類別。
下面我們來增加一個plist文件記錄我們后面需要使用的數據。
1. 在“My Focus”上點鼠標右鍵,在彈出菜單中選擇“New Group”,然后輸入“Data”做為新建群組的名稱,見下圖:
2. 在“Data”上點鼠標右鍵,選擇“New File...”,然后選擇“Resource”“Property List”,然后點擊“Next”按鈕,見下圖:
3. 在“Save As”輸入“FocusUsers”做為數據文件的名稱,然后點“Create”按鈕,見下圖:
4. 在新建的“FocusUsers.plist”文件上點鼠標右鍵,選擇“Open As”“Source Code”,我們可以看到所謂屬性文件,原來是一個xml文件。將以下代碼復制替換現有的xml內容。
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 <dict> 6 <key>UserName</key> 7 <string>愛Apps</string> 8 <key>Image</key> 9 <string>愛Apps.jpeg</string> 10 <key>WebSite</key> 11 <string>http://weibo.com/iapps</string> 12 <key>Category</key> 13 <string>蘋果咨詢</string> 14 <key>Favorite</key> 15 <real>3.5</real> 16 </dict> 17 <dict> 18 <key>UserName</key> 19 <string>蘋果匯</string> 20 <key>Image</key> 21 <string>蘋果匯.jpeg</string> 22 <key>WebSite</key> 23 <string>http://weibo.com/appleus</string> 24 <key>Favorite</key> 25 <real>3.5</real> 26 <key>Category</key> 27 <string>蘋果咨詢</string> 28 </dict> 29 <dict> 30 <key>UserName</key> 31 <string>數碼iPhone大百科</string> 32 <key>Image</key> 33 <string>數碼iPhone大百科.jpeg</string> 34 <key>WebSite</key> 35 <string>http://weibo.com/gx110</string> 36 <key>Favorite</key> 37 <real>3.5</real> 38 <key>Category</key> 39 <string>蘋果咨詢</string> 40 </dict> 41 <dict> 42 <key>UserName</key> 43 <string>新浪視野</string> 44 <key>Image</key> 45 <string>新浪視野.jpeg</string> 46 <key>WebSite</key> 47 <string>http://weibo.com/wboard</string> 48 <key>Favorite</key> 49 <real>3.5</real> 50 <key>Category</key> 51 <string>官方機構</string> 52 </dict> 53 <dict> 54 <key>UserName</key> 55 <string>李開復</string> 56 <key>Image</key> 57 <string>李開復.jpeg</string> 58 <key>WebSite</key> 59 <string>http://weibo.com/kaifulee</string> 60 <key>Favorite</key> 61 <real>3.5</real> 62 <key>Category</key> 63 <string>IT名人</string> 64 </dict> 65 </array> 66 </plist>
提示:plist文件是xml文件的一種特例,由“鍵名”“鍵值”成對組成,在iOS開發中,plist的使用要比xml簡單些,我們演練中選擇plist文件存儲數據。
5. 在“FocusUsers.plist”文件上點鼠標右鍵,選擇“Open As”“Property List”,可以看到屬性表形式的內容,見下圖:
在開始下一步工作之前,我們還需要准備一些圖片,猛擊此處 MyFocusDemo2Images.zip 下載本演練需要使用的圖片文件。
下載完成后,將Images文件夾從Finder中拖到“My Focus”下並放手,見下圖:
點擊“Finish”按鈕。此時導航區域看起來應該是下圖的樣子 :]
好,到此為止,我們的准備工作基本告一段落了,下面我們將繼續第一講的內容,對代碼進行調整。
二. 從plist文件加載並顯示數據
我們仍然打開“JOYTableViewController.m”文件,開始我們的編碼工作。
1. 修改私有變量_userList的類型,將其改為:“NSMutableArray”,代碼如下:
1 @interface JOYTableViewController () { 2 @private 3 NSMutableArray *_userList; 4 }
2. 在viewDidLoad方法中添加幾行代碼,由plist文件中的內容來填充_userList,代碼如下:
1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 5 // 設定pList文件路徑 6 NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"FocusUsers.plist" ofType:nil]; 7 // 填充數組內容 8 _userList = [NSMutableArray arrayWithContentsOfFile:dataPath]; 9 10 }
小技巧:設定文件路徑時,如果在“ofType”的參數是nil,則可以在pathForResource中使用文件全名。我也是剛剛知道這一技巧,忍不住在代碼中就用上了,呵呵。
3. 修改 - (UITableViewCell *)tableView 方法中設置文本部分的代碼。將原有的設置文本的語句刪除,因為現在數組中保存的已經不是一個個字符串了,而是一個個字典了,替換成以下兩句代碼:
1 NSDictionary *item = [_userList objectAtIndex:indexPath.row]; 2 [cell.textLabel setText:[item objectForKey:@"UserName"]];
替換之后,這個方法完整看起來應該是這個樣子:
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 // 設置單元格文本 13 NSDictionary *item = [_userList objectAtIndex:indexPath.row]; 14 [cell.textLabel setText:[item objectForKey:@"UserName"]]; 15 16 return cell; 17 }
好,現在我們運行一下看一下效果,見下圖:
運行效果雖然和上一篇演練結束前的結果看起來一樣,不過我們現在可是從plist中加載的數據哦。不過說實話,這個運行界面真的不是很美觀。
下面讓我們來想辦法讓界面看起來好那么一點,最起碼要比現在好些。
三. 在表格中顯示頭像並調整表格樣式
在本篇第一步准備工作中,朋友們應該發現准備了家長頭像圖片,在本節中我們就來把這些頭像顯示在表格中。:]
在剛剛增加代碼的代碼下面增加一句:
1 // 顯示頭像 2 [cell.imageView setImage:[UIImage imageNamed:[item objectForKey:@"Image"]]];
現在我們再運行看看效果。
頭像已經顯示出來了,怎么樣?簡單吧,哈哈。
現在我們想改變一下文字的顯示效果,變換一個字體,調整一下大小,改變一下顏色,以及對齊方向。
我們在設定文本內容那句話下面增加如下代碼:
1 // 設定字體 2 [cell.textLabel setFont:[UIFont fontWithName:@"Helvetica" size:16.0f]]; 3 // 改變字體顏色 4 [cell.textLabel setTextColor:[UIColor orangeColor]]; 5 // 調整文本居中對齊 6 [cell.textLabel setTextAlignment:UITextAlignmentCenter];
現在我們再運行看看效果。
怎么樣?還算滿意嗎?:]當然現在這個樣子,距離商業化的應用還有不小的差距,不過已經比第一章演練完成時取得了不小的進步了。
四. 使用數據模型
細心的朋友可能已經發現,前一部分我們在設置文本內容和圖像時,使用了:
[item objectForKey:@"UserName"] [item objectForKey:@"Image"]
這樣的方法。說實話,這真的不是一個好習慣,尤其對復雜應用而言,我們要盡可能將數據和界面區分開,否則一旦數據結構發生變化,程序員需要在程序中查找所有類似的地方進行修改,這是一個很痛苦的事情。
下面我們演練如何增加一個數據類將用戶信息的處理抽取出來,讓程序看起來更優雅一些。
1. 在導航區域“My Focus”上點擊鼠標右鍵,在彈出菜單中選擇“Add Group”,然后輸入“Model”做為新建群組的名稱。見下圖:
2. 在“Model”上,點擊鼠標右鍵,在彈出菜單中選擇“New File...”,在彈出窗口中選擇“Cocoa Touch”“Objective-C class”,然后點“Next”按鈕,見下圖:
3. 在“Class”中輸入“JOYFocusUser”,“Subclass of”中輸入“NSObject”,然后點擊“Next"按鈕,見下圖:
4. 在接下來的窗口中,我們直接點擊“Create”按鈕創建這個文件,此時我們的導航區域如下圖所示:
5. 點擊打開“JOYFocusUser.h”文件,在接口中輸入如下代碼:
1 @interface JOYFocusUser : NSObject 2 3 @property (strong, nonatomic) NSString *userName; 4 @property (strong, nonatomic) UIImage *image; 5 @property (strong, nonatomic) NSString *webSite; 6 @property (assign, nonatomic) CGFloat favorite; 7 @property (strong, nonatomic) NSString *categoryName; 8 9 // 使用字典項目實例化對象屬性 10 - (id)initWithItem:(NSDictionary *)item; 11 12 @end
其中3~7句一次定義了數據模型的屬性,第10句定義了一個方法,用於實例化數據模型,供外部對象調用。
提示:與前一篇演練中提到的不同,因為數據模型的屬性和方法需要被其他對象訪問,所以這些屬性和方法需要在.h文件中定義才可以。
6. 點擊打開“JOYFocusUser.m”文件,在實現中輸入如下代碼:
1 #import "JOYFocusUser.h" 2 3 @implementation JOYFocusUser 4 @synthesize userName = _userName; 5 @synthesize image = _image; 6 @synthesize webSite = _webSite; 7 @synthesize favorite = _favorite; 8 @synthesize categoryName = _categoryName; 9 10 - (id)initWithItem:(NSDictionary *)item { 11 12 self = [super init]; 13 if (self) { 14 _userName = [item objectForKey:@"UserName"]; 15 _image = [UIImage imageNamed:[item objectForKey:@"Image"]]; 16 _webSite = [item objectForKey:@"WebSite"]; 17 _favorite = [[item objectForKey:@"Favorite"]floatValue]; 18 _categoryName = [item objectForKey:@"Category"]; 19 } 20 return self; 21 } 22 23 @end
小提示:按住 control + command + 上下方向鍵,可以在.h和.m文件之間來回切換。:]
到此為止,我們的數據模型已經准備好了,下面我們來看看如何使用這個模型。
1. 點擊打開“JOYTableViewController.m”文件,在文件頂部的#import "JOYTableViewController.h"之后加入:
1 #import "JOYFocusUser.h"
2. 在 - (void)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 // 初始化一個空的用戶列表數組 11 _userList = [[NSMutableArray alloc]init]; 12 for (NSDictionary *item in array) { 13 JOYFocusUser *user = [[JOYFocusUser alloc]initWithItem:item]; 14 [_userList addObject:user]; 15 } 16 17 }
說明:以上代碼使用了一個for循環,依次建立用戶實例並添加到_userList數組中。
3. 在 - (UITableViewCell *)tableView 方法中,我們需要修改三句話:
1 // 設置單元格文本 2 // NSDictionary *item = [_userList objectAtIndex:[indexPath row]]; 3 JOYFocusUser *user = [_userList objectAtIndex:[indexPath row]]; 4 // [cell.textLabel setText:[item objectForKey:@"UserName"]]; 5 [cell.textLabel setText:[user userName]];
1 // 顯示頭像 2 // [cell.imageView setImage:[UIImage imageNamed:[item objectForKey:@"Image"]]]; 3 [cell.imageView setImage:[user image]];
此時我們運行一下程序,與上一部分完成時的效果,並沒有發生任何變化。
不過在程序方面,我們導入了一個數據模型,這樣使得我們只是在程序加載時,實例化一次數組項目即可,以后調用時,我們可以直接針對這個數據模型進行操作了。:]
為了方便大家閱讀,我在上面貼的代碼中,注釋了前面使用過的代碼,這樣能夠方便大家體會兩種方式之間的區別。
五. 小結
本次演練到此結束,到目前為止,我們已經實現了一個從plist加載數據的表格應用。:]
本演練源程序下載地址:JoyiOSMyFocus2.zip
下一篇文章我們會演練如何將現有數據分區段顯示,以及如何自定義單元格內容。敬請期待。:]