首先向大家致歉,自從上一篇使用 UITableView 創建表格應用演練(3)——使用區段分類顯示表格數據博文發布后,因工作原因始終未能抽出時間更新博客。
今天給大家介紹一下如何在表格應用中使用自定義單元格以及選中單元格的一個簡單操作。
本文目標
本文以上一篇為基礎,對應用進行擴展,介紹以下內容:
- 在表格應用中自定義單元格布局顯示;
- 選中某一單元格,並在Safari中打開用戶鏈接地址;
一. 自定義單元格演練
首先我們回顧一下前文,在演練(2)中,我們定義數據結構時,定義了一個名為:Favorite的屬性,用於表示我們對該微博賬戶的喜好程度。本節演練中,我們就通過自定義單元格的方式,在表格中以五角星的形式顯示喜好程度,本節演練結束后,您將看到以下運行結果:
開始之前,我們需要准備幾張星星的圖片,請猛擊此處MyFocusDemo4Images.zip下載。
准備就緒,讓我們開始吧:D
1. 打開My Focus工程;
2. 將下載並解壓縮后的三個圖片文件拖拽到“Images”組下並放手,彈出下圖對話框:
確認勾選了“Copy items into destination groups' folder(if needed)”復選框后,點擊“Finish”按鈕;
3. 在導航區域點擊並打開“MainStoryboard.storyboard”文件,在左側“Table View Controller Scene”中展開並選中“Table View Cell - userInfoCell”,此時的界面如下圖所示:
4. 在右側工具區域的“Objects”列表中選擇一個ImageView控件拖放到表格單元左側,然后我們再選擇一個Label控件,拖放到剛剛那個ImageView的右側,然后再依次拖放五個ImageView控件,順序擺放在Label控件的右側。在此,我們可以用鼠標調整一下各個控件的大小和位置,使得界面看起來更加美觀一些。我們甚至還可以調整一下Label控件的文本顏色。如下圖所示:
5. 此時,按Command+R運行一下程序,怎么和上次演練之后的運行結果一樣呢?沒有發生任何變化啊。
對,因為我們還沒有告訴應用怎么和我們剛才調整過的界面結合再一起,下面我們就來做這個工作。
6. 在導航區域的“GUI”群組文件夾上,點擊鼠標右鍵,選擇“New File...”在彈出的對話框中選擇“Objective-C class”,然后點擊“Next”按鈕;
7. 在彈出的“Choose options for your new file”對話框中,在“Class”文本框位置輸入:JOYUserInfoCell,在“Subclass of”下拉框中,選擇或者直接輸入“UITableViewCell”,然后點擊“Next”按鈕,如下圖所示:
8. 在彈出的對話框中,直接點擊“Create”按鈕,創建文件並關閉對話框;
9. 在導航區域點擊並打開新建的“JOYUserInfoCell.h”文件,輸入屬性定義代碼,輸入完成后,如下所示:
1 #import <UIKit/UIKit.h> 2 3 @interface JOYUserInfoCell : UITableViewCell 4 5 @property (strong, nonatomic) IBOutlet UIImageView *userImage; 6 @property (strong, nonatomic) IBOutlet UILabel *userNameLabel; 7 @property (strong, nonatomic) IBOutlet UIImageView *favoriteImage1; 8 @property (strong, nonatomic) IBOutlet UIImageView *favoriteImage2; 9 @property (strong, nonatomic) IBOutlet UIImageView *favoriteImage3; 10 @property (strong, nonatomic) IBOutlet UIImageView *favoriteImage4; 11 @property (strong, nonatomic) IBOutlet UIImageView *favoriteImage5; 12 13 @end
10. 在導航區域點擊並打開新建的“JOYUserInfoCell.m”文件,@implementation語句后輸入一些@synthesize屬性定義語句,如下所示:
1 @implementation JOYUserInfoCell 2 // 1. 屬性合成定義 3 @synthesize userImage = _userImage; 4 @synthesize userNameLabel = _userNameLabel; 5 @synthesize favoriteImage1 = _favoriteImage1; 6 @synthesize favoriteImage2 = _favoriteImage2; 7 @synthesize favoriteImage3 = _favoriteImage3; 8 @synthesize favoriteImage4 = _favoriteImage4; 9 @synthesize favoriteImage5 = _favoriteImage5;
說明:所謂屬性合成定義,是對getter、setter的一種簡化表現形式。這樣,我們可以避免寫很多很多的,說實話,大量的getter、setter是一個很痛苦的事情。當然,在Objective-c中,您也可以自己來寫getter和setter,稍后演練中會有所涉及。
11. 在導航區域,再次點擊並打開“MainStoryboard”文件,下面我們來看看如何將界面的UI控件和類屬性成員進行綁定:D。
12. 在左側“Table View Controller Scene”面板中,選中“User Info Cell - userInfoCell”,然后在右側工具區域頂部,選擇“Show the Identity inspector”,然后在下方的“Custom Class”區域的“Class”下拉列表中,將原有的“UITableViewCell”修改為我們剛剛定義的“JOYUserInfoCell”,如下圖所示:
13. 在左側“Table View Controller Scene”面板中,確認點擊並選中“User Info Cell - userInfoCell”(有時候焦點可能會丟失,再點一下就好了),然后在右側工具區域頂部,選擇“Show the Connections inspector”,如下圖所示:
看到什么了?對!就是我們剛才在 JOYUserInfoCell.h 中定義的那些 IBOutlet 屬性。
說明:IB是Interface Builder的縮寫,如果您希望定義的屬性在Interface Builder中可見,則在屬性定義時加上 IBOutlet 關鍵字即可。
14. 在右側面板的Outlets區域中,將鼠標指針移動到“userImage”右側的空心圓點上時,該圓點會變成一個灰色的加號,點擊並按住鼠標,然后拖放到左側面板的第一個“Image View”上放手,拖拽過程中會有一條灰色的線條出現。這樣我們第一個連接就建立好了,如下圖所示:
15. 下面我們依次建立其他控件與自定義類的連接關系,建立完成之后的效果,如下圖所示:
說明:建立連接的過程中,需要注意控件與屬性的關系是否一一對應,在右側“Outlets”面板中,上下移動鼠標,隨着指針的移動,中心區域的控件會根據鼠標所在位置高亮顯示。如果發現錯了,您可以點擊右側面板中的小叉子,刪除連接關系,然后重復上述操作,重新建立連接。
啰嗦了半天,寫了很多的字,實際上等熟練,之后,你會發現這個操作是非常的簡單和省時的,也是一件非常快樂的事情。
16. 開始下一步之前,我們先做一個操作,因為這個操作馬上就要用到。還記得我們在演練(1)建立UITableViewController的時候,曾經設定過表格單元的“Identifier”嗎?如下圖所示:
可是這個設定貌似一直沒有用過,不要着急,不要着急,馬上就要用到了:D
17. 按Command+R再次運行程序,怎么還是和上次演練之后的運行結果一樣呢?忙乎了這么久,為什么一點變化也沒有呢?
因為我們還沒有告訴程序如何識別表格單元。下面我們來看看如何做吧。
18. 在導航區域點擊並打開我們久違的“JOYTableViewController.m”文件,找到- (UITableViewCell *)tableView方法,我們先看一下前幾句代碼:
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...
這是在創建對象時,系統默認生成的代碼。看到了嗎?
對,就是這里出了問題!下面我們將方法中的代碼進行簡單的調整,調整之前,我們先在文件頭部加上一句:
1 #import "JOYUserInfoCell.h"
否則編譯器不知道去哪里找 JOYUserInfoCell 這個類,調整后的代碼如下所示:
1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 2 { 3 // 1. 修改單元格標示 4 static NSString *CellIdentifier = @"userInfoCell"; 5 // 2. 修改單元格屬性,使其繼承自 JOYFocusUserCell 6 JOYUserInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 7 8 // Configure the cell... 9 // 實例化單元格對象 10 if (cell == nil) { 11 // 3. 修改示例化對象屬性 12 cell = [[JOYUserInfoCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 13 } 14 15 JOYCategory *category = [_categoryList objectAtIndex:[indexPath section]]; 16 JOYFocusUser *user = [category.userList objectAtIndex:[indexPath row]]; 17 18 // 4. 設置單元格屬性 19 [cell.userNameLabel setText:user.userName]; 20 [cell.userImage setImage:user.image]; 21 22 return cell; 23 }
下面我們來做根據不同用戶的Favorite數值,在用戶名稱的左側顯示五角星。
19. 在導航區域,點擊並打開“JOYUserInfoCell.h”文件,在 IBOutlet 屬性下方,添加一個屬性,代碼如下:
1 #import <UIKit/UIKit.h> 2 3 @interface JOYUserInfoCell : UITableViewCell 4 5 @property (strong, nonatomic) IBOutlet UIImageView *userImage; 6 @property (strong, nonatomic) IBOutlet UILabel *userNameLabel; 7 @property (strong, nonatomic) IBOutlet UIImageView *favoriteImage1; 8 @property (strong, nonatomic) IBOutlet UIImageView *favoriteImage2; 9 @property (strong, nonatomic) IBOutlet UIImageView *favoriteImage3; 10 @property (strong, nonatomic) IBOutlet UIImageView *favoriteImage4; 11 @property (strong, nonatomic) IBOutlet UIImageView *favoriteImage5; 12 13 @property (assign, nonatomic) CGFloat favorite; 14 15 @end
20. 按 Control + Command + 下箭頭直接打開“JOYUserInfoCell.m”文件,添加部分代碼,具體調整見以下代碼中的注釋。
1 #import "JOYUserInfoCell.h" 2 3 // 1. 接口定義 4 @interface JOYUserInfoCell() { 5 // 2. 私有成員變量 6 @private 7 CGFloat _favorite; // 喜好程度數值 8 9 UIImage *_fullStarImage; // 完整星星圖像 10 UIImage *_halfStarImage; // 半顆星星圖像 11 UIImage *_emptyStarImage; // 空白星星圖像 12 } 13 14 @end 15 16 @implementation JOYUserInfoCell 17 @synthesize userImage = _userImage; 18 @synthesize userNameLabel = _userNameLabel; 19 @synthesize favoriteImage1 = _favoriteImage1; 20 @synthesize favoriteImage2 = _favoriteImage2; 21 @synthesize favoriteImage3 = _favoriteImage3; 22 @synthesize favoriteImage4 = _favoriteImage4; 23 @synthesize favoriteImage5 = _favoriteImage5; 24 25 // 3. 26 #pragma mark - getter & setter 27 // 設置喜好數值 28 - (void)setFavorite:(CGFloat)favorite { 29 _favorite = favorite; 30 } 31 32 // 返回喜好數值 33 - (CGFloat)favorite { 34 return _favorite; 35 } 36 37 // 4. 添加程序運行時對象初始化方法 38 - (id)initWithCoder:(NSCoder *)aDecoder { 39 self = [super initWithCoder:aDecoder]; 40 41 if (self) { 42 _fullStarImage = [UIImage imageNamed:@"star_full.png"]; 43 _halfStarImage = [UIImage imageNamed:@"star_half.png"]; 44 _emptyStarImage = [UIImage imageNamed:@"star_empty.png"]; 45 } 46 return self; 47 } 48 49 //- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 50 //{ 51 // self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 52 // if (self) { 53 // // Initialization code 54 // } 55 // return self; 56 //} 57 58 - (void)setSelected:(BOOL)selected animated:(BOOL)animated 59 { 60 [super setSelected:selected animated:animated]; 61 62 // Configure the view for the selected state 63 } 64 65 @end
21. 下面我們來對setFavorite的實現做一些簡單的處理,代碼如下:
1 // 設置喜好數值 2 - (void)setFavorite:(CGFloat)favorite { 3 // A. 數值范圍校驗 4 if ((favorite > 5.0f) || (favorite < 0.0f)) { 5 favorite = 0.0f; 6 } 7 8 // B. 定義數值便於循環處理 9 [self.favoriteImage1 setImage:_emptyStarImage]; 10 NSArray *favoriteImages = [[NSArray alloc]initWithObjects:_favoriteImage5, 11 _favoriteImage4, 12 _favoriteImage3, 13 _favoriteImage2, 14 _favoriteImage1, 15 nil]; 16 17 // C. 依次判斷每個UIImageView應該顯示的圖像內容 18 NSInteger x = favorite * 10; 19 for (NSInteger i = 5; i > 0; i--) { 20 UIImageView *image = [favoriteImages objectAtIndex:(5 - i)]; 21 22 if ((x / 10) >= i) { 23 [image setImage:_fullStarImage]; 24 } else if (((x % 10) > 0) && ((x / 10) == (i - 1))) { 25 [image setImage:_halfStarImage]; 26 } else { 27 [image setImage:_emptyStarImage]; 28 } 29 } 30 31 _favorite = favorite; 32 }
22. 在導航區域點擊並打開“JOYTableViewController.m”文件,找到- (UITableViewCell *)tableView方法,在設置頭像語句后面添加一句:
1 cell.favorite = user.favorite;
23. 按Command+R再次運行程序,激動人心的時刻到了!!!如下圖所示:
怎么樣,效果還不錯吧,而且不復雜吧:D,本節內容貌似寫了不少,其實大部分時間都是在用鼠標拖來拖去,真正寫代碼的時間還是很少的。
二. 選中某一單元格並在Safari中打開用戶鏈接地址
1. 在導航區域,點擊並打開“JOYUserInfoCell.h”文件,在 IBOutlet 屬性下方,添加一個屬性,代碼如下:
1 @property (strong, nonatomic) NSString *webSite;
2. 按 Control + Command + 下箭頭直接打開“JOYUserInfoCell.m”文件,在
@implementation JOYUserInfoCell
語句下,添加 @synthesize 屬性定義,代碼如下:
1 @synthesize webSite = _webSite;
3. 修改文件末尾的setSelected方法,代碼如下:
1 - (void)setSelected:(BOOL)selected animated:(BOOL)animated 2 { 3 [super setSelected:selected animated:animated]; 4 5 // Configure the view for the selected state 6 if (selected) { 7 NSURL *url = [NSURL URLWithString:_webSite]; 8 9 if (![[UIApplication sharedApplication]openURL:url]){ 10 NSLog(@"%@%@",@"Failed to open url:",[url description]); 11 } 12 } 13 }
4. 在導航區域點擊並打開“JOYTableViewController.m”文件,找到- (UITableViewCell *)tableView方法,在設置頭像語句后面添加一句:
cell.webSite = user.webSite;
5. 按Command+R再次運行程序,然后點擊某一個單元格試試看運行效果。:D
三. 小結
至此,表格應用演練算是基本告一段落了。原本還打算在本演練中寫一些有關Navigation控件的使用以及數據編輯存儲相關內容的。
但是考慮到類似文章網上已經有不少了,另外本人前段時間工作原因導致這個演練系列拖得有點久,再次表示歉意。
本演練源程序下載地址:JoyiOSMyFocus4.zip
近期計划寫一些有關Objective-C語法相關的演練教程,敬請關注。