使用模板建立UITableView
該案例為黑馬程式設計師IOS基礎UI視訊教程第九天案例
該案例中主要使用UITableView中自帶的模板來建立UITableViewCell,這種方式可以無需在建立xib檔案,無需再重寫initWithStyle方法,略方便一點。案例中也使用了一些其他的小知識點,如:將訊息框加入到視窗介面而不是UITableView中、設定文字框的圓角顯示等
本案例主要實現的功能有三點:
- 根據plist檔案建立UITableView並顯示出資料;
- 點選按鈕後按鈕變為已下載並彈出提示框提示下載過程;
- 點選一次下載後按鈕始終顯示為已下載並不可點選;
實現的最終效果如下圖所示

最終效果.png
該案例的實現思路與使用xib檔案的實現思路幾乎完全相同,只是將原先xib檔案換為了tableview的單元格模板。使用單元格模板時直接重用就可以了,無需考慮快取池中不存在單元格以供重用的情況。
第一步:匯入素材、字典轉模型、懶載入
第二步:建立介面,建立cell模板,建立對應controller類和cell類並掛接
第三步:在cell類中新增模型屬性,實現模型屬性的set方法,在方法中為各控制元件賦值
第四步:實現UITableView的資料來源方法,使cell顯示出來
第五步:為下載按鈕註冊單擊事件,在事件中實現狀態的轉換並顯示訊息提示框
-
實現狀態轉換:因為單元格被點選一次以後不允許再次被點選,也就是說需要有一個屬性來記錄單元格是否被點選,保證即使單元格被重用也不會出錯。這就需要在模型中新增一個屬性來記錄
@property(nonatomic , assign) Boolean isDownload
。當點選按鈕時,一方面將按鈕的enable
設定為NO
,另一方面將isDownload
設定為NO
-
顯示訊息提示框:因為按鈕的單擊事件是在cell類中實現的,cell類中無法顯示提示框,因此需要通過代理事件來實現,為cell自定義一個delegate方法,cell建立時將其delegate屬性指定為控制器本身,使控制器遵守這個代理協議並實現代理方法,在代理方法內部實現訊息提示框的動畫效果
代理方法:
@class LJAppCell; @protocol LJAppCellDelegate <NSObject> -(void)downloadDidClick:(LJAppCell *)appcell; @end @class LJApp; @interface LJAppCell : UITableViewCell //資料模型 @property(nonatomic , strong) LJApp * app_model; //delegate屬性 @property(nonatomic , weak) id<LJAppCellDelegate> delegate; @end
在單擊事件中呼叫代理方法:
if ([self.delegate respondsToSelector:@selector(downloadDidClick:)]) { //呼叫代理方法 [self.delegate downloadDidClick:self]; }
在控制器中實現代理方法:
-(void)downloadDidClick:(LJAppCell *)appcell { //建立一個label並加入到當前的螢幕中,注意,不要加入到當前的tableView中,否則會隨著tableView的滑動而滑動 UILabel * lbl_message = [[UILabel alloc] init]; [[[UIApplication sharedApplication] keyWindow] addSubview:lbl_message]; //設定lable的相關屬性 //背景色 lbl_message.backgroundColor = [UIColor grayColor]; //文字顏色與文字內容 lbl_message.textColor = [UIColor redColor]; lbl_message.text = @"正在下載·····"; //文字對齊方式 lbl_message.textAlignment = NSTextAlignmentCenter; //文字大小 lbl_message.font = [UIFont systemFontOfSize:20.0]; //設定文字框的圓角顯示效果 lbl_message.layer.cornerRadius = 5; lbl_message.clipsToBounds = YES; //透明度 lbl_message.alpha = 0; //設定frame CGFloat lbl_messageW = 250; CGFloat lbl_messageH = 50; //通過[[UIScreen mainScreen] bounds]來獲取當前螢幕的尺寸 CGFloat lbl_messageX = ([[UIScreen mainScreen] bounds].size.width - lbl_messageW)/2; CGFloat lbl_messageY = ([[UIScreen mainScreen] bounds].size.height - lbl_messageH)/2; lbl_message.frame = CGRectMake(lbl_messageX, lbl_messageY, lbl_messageW, lbl_messageH); //動畫實現lable的出現和消失,通過改變label的透明度來實現 [UIView animateWithDuration:0.8 animations:^{ lbl_message.alpha = 1; } completion:^(BOOL finished) { if (finished) { [UIView animateWithDuration:0.8 delay:2.0 options:UIViewAnimationOptionCurveLinear animations:^{ lbl_message.alpha = 0; } completion:^(BOOL finished) { [lbl_message removeFromSuperview]; }]; } }]; }
- 避免單元格在重用時出現下載狀態的錯誤顯示:由於模型中已有屬性記錄該模型是否已被下載,因此可以讓每個單元格在顯示時就進行一次判斷,如果已下載則不可點選,如果未下載則可以點選,這段程式碼可以放在cell模型中對模型資料的set方法重寫時執行
//根據模型資料中是否已下載來設定按鈕 if (app_model.isDownload) { //使按鈕不可點選 self.btn_download.enabled = NO; } else { //使按鈕可點選 self.btn_download.enabled = YES; }
由於本人水平有限,不當之處還請批評指正。初學IOS,希望大家一起交流一起進步~