本來不打算寫UITableView的,因為網上已經有很多這方面的文章,尤其是 趣味蘋果開發中的TableViewController系列 已經有很詳細的講解了。但是群里還是有很多童鞋會問這方面的問題,所以在這里以自己的理解方式比划一下。
讓我們先來看一張從模擬器截下來的圖:
上圖是一個UITableView列表,紅色的1、2、3、4、5...是一個個的UITableViewCell。
從這張截圖我們可以看出來 UITableView 是由一系列 UITableViewCell 組成的列表,由此我們可以知道 UITableViewCell 在 UITableVeiw 中的重要性了。
在真實地項目中,UITableViewCell 中的各項內容的排列都不同(如上圖4中的 2013年、全國等),它自帶的那幾種樣式根本無法滿足我們的需求,所以這就需要我們來自定義自己的Cell(下文中的Cell都表示UITableViewCell)了。
以上圖中的Cell為例,我們來自定義一個UITableViewCell。首先我們來創建一個應用——CustomTableVeiwCellDemo,打開XCode,選擇File -> New -> Project...,如下圖所示:
然后選擇iOS->Application->Single View Application,然后點Next,如下圖所示:
在Product Name中輸入“CustomTableVeiwCellDemo”,其他設置部分參照下圖:
然后點Next,保存到磁盤適當的位置,至此我們的Xcode應該是下圖這個樣子:
工程創建完成了,然后開始我們的UITableView之旅吧。
首先我們需要有一個UITableView,那么我們給上圖中的WViewController.xib上拖拽一個UITableVeiw,然后綁定UITableView的dataSource與delegate到WViewController上,如下圖:
我們給UITableView設置個名稱為tableView
並給WViewController.h 設置 dataSource、delegate的代理,代碼如下:
// // WViewController.h // CustomTableVeiwCellDemo // // Created by wzrong on 13-8-15. // Copyright (c) 2013年 wzrong. All rights reserved. // #import <UIKit/UIKit.h> @interface WViewController : UIViewController<UITableViewDataSource, UITableViewDelegate> @property (strong, nonatomic) IBOutlet UITableView *tableView; @end
然后在WViewController.m中實現dataSource與delegate的部分方法,如 UITableView的區段數、UITableView的行數、指定行的UITableVeiwCell、單擊單元格的處理等
#pragma mark - UITableView methods /** 1、返回 UITableView 的區段數 */ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ } /** 2、返回 UITableView 的行數 */ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ } /** 3、設置行的高度 */ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ } /** 4、返回指定的 row 的 cell */ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ } /** 5、點擊單元格時的處理 */ -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ }
接下來我們按照上邊注釋的步驟來填充方法
1、本例中我們只需要一個區段,所以返回1就ok了。
/** 1、返回 UITableView 的區段數 */ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; }
2、要知道返回的行數,首先我們需要知道有多少條數據,到目前為止,我們還沒有定義要顯示的數據,所以先讓我們來定義要顯示在UITableView上的數據吧。
2.1 我們需要顯示的是年份、省份、標題,所以首先我們定義一個試卷模型WPaperModel,用來存放顯示的這些屬性。
右鍵工程->New Group,創建一個組Model,
選擇Model,在點擊下圖1的位置,創建一個Model文件夾與之相關聯
在Model里邊添加文件WPaperModel,並添加相應的屬性,並初始化模型對象,代碼如下:
WPaperModel.h
// // WPaperModel.h // CustomTableVeiwCellDemo // // Created by wzrong on 13-8-15. // Copyright (c) 2013年 wzrong. All rights reserved. // // 試卷模型 // #import <Foundation/Foundation.h> @interface WPaperModel : NSObject @property (nonatomic, assign) NSInteger paperID; // 試卷代號 @property (nonatomic, strong) NSString *paperYear; // 試卷所屬年份 @property (nonatomic, strong) NSString *paperProvince; // 試卷所屬省份 @property (nonatomic, strong) NSString *paperTitle; // 試卷標題 /** 初始化試卷模型對象 @param paperId 試卷代號 @param year 試卷年份 @param province 試卷省份 @param title 試卷標題 */ - (id)initWithPaperID:(NSInteger)paperId paperYear:(NSString *)year paperProvince:(NSString *)province paperTitle:(NSString *)title; @end
WPaperModel.m
// // WPaperModel.m // CustomTableVeiwCellDemo // // Created by wzrong on 13-8-15. // Copyright (c) 2013年 wzrong. All rights reserved. // // 試卷模型 // #import "WPaperModel.h" @implementation WPaperModel /** 初始化試卷模型對象 @param paperId 試卷代號 @param year 試卷年份 @param province 試卷省份 @param title 試卷標題 */ - (id)initWithPaperID:(NSInteger)paperId paperYear:(NSString *)year paperProvince:(NSString *)province paperTitle:(NSString *)title{ self = [super init]; if (self) { self.paperID = paperId; self.paperYear = year; self.paperProvince = province; self.paperTitle = title; } return self; } @end
2.2 在WViewController.m中定義要顯示的數據,把這些數據初始化到數據模型中,並把數據模型添加到要展示在UITableView的列表集合中,代碼如下:
定義數據數組與試卷列表
@interface WViewController (){ NSArray *_dataArray; // 數據數組 NSMutableArray *_paperList; // 試卷列表 }
初始化數據數組、試卷列表與試卷模型,並把試卷模型添加到試卷列表中
- (void)viewDidLoad { [super viewDidLoad]; // 初始化數據數組 _dataArray = @[@[@"2013", @"北京", @"2012-2013學年北京市石景山區初一下學期期末考試數學試卷(帶解析)"], @[@"2013", @"江蘇", @"2012-2013學年江蘇蘇州市景范中學初二第二學期期末考試數學試卷(帶解析)"], @[@"2013", @"湖北", @"2013年湖北省恩施州初中數學評價《實數與代數式》單元試卷(一)(帶解析)"], @[@"2013", @"全國", @"2013人教版初中數學七年級上冊第一章有理數練習卷(帶解析)"], @[@"2013", @"湖北", @"2013年初中畢業升學考試(湖北十堰卷)數學(帶解析)"]]; // 初始化試卷列表 _paperList = [[NSMutableArray alloc]init]; for (int i=0; i<_dataArray.count; i++) { // 初始化試卷模型 WPaperModel *paperModel = [[WPaperModel alloc]initWithPaperID:i paperYear:_dataArray[i][0] paperProvince:_dataArray[i][1] paperTitle:_dataArray[i][2]]; // 添加試卷模型到試卷列表中 [_paperList addObject:paperModel]; } }
2.3 至此我們知道了要展示在UITableView上邊的數據列表為_paperList了,那么也就知道了UITableView的行數了,所以就可以設置行數了
/** 2、返回 UITableView 的行數 */ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return _paperList.count; }
3、由於我們要自定義Cell,所以行的高度也就是自定義Cell的高度,接下來我們就自定義Cell,起名為 WPaperCell
3.1 與上邊2.1類似,先建立一個View組,然后關聯到View文件夾中,再然后在View中創建WPaperCell,如下圖:
3.2 創建完成后,我們為WPaperCell建立相對應的WPaperCell.xib文件,如下圖我們選擇iOS -> Use Interface -> Empty,然后點擊Next
然后拖拽一個UITableViewCell到WPaperCell.xib上,並與WPaperCell類關聯
3.3 給Cell上拖拽3個UILabel,用來顯示年、省份、標題,設置Identifier標識符為paperCell,Accessory的值為Disclosure Indicator,如下圖:
上圖中UILabel的線框,可以參考 iOS 開發問題集錦(二) 中的第2個問題。
3.4 給3個UILabel設置名稱,並初始化,代碼如下:
WPaperCell.h
// // WPaperCell.h // CustomTableVeiwCellDemo // // Created by wzrong on 13-8-15. // Copyright (c) 2013年 wzrong. All rights reserved. // // 自定義UITableViewCell // #import <UIKit/UIKit.h> #import "WPaperModel.h" @interface WPaperCell : UITableViewCell @property (strong, nonatomic) IBOutlet UILabel *lblYear; // 年標簽 @property (strong, nonatomic) IBOutlet UILabel *lblProvince; // 省份標簽 @property (strong, nonatomic) IBOutlet UILabel *lblTitle; // 標題標簽 /** 設置Cell */ -(void)setupCell:(WPaperModel *)model; @end
WPaperCell.m
// // WPaperCell.m // CustomTableVeiwCellDemo // // Created by wzrong on 13-8-15. // Copyright (c) 2013年 wzrong. All rights reserved. // #import "WPaperCell.h" @implementation WPaperCell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code } return self; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } /** 設置Cell */ -(void)setupCell:(WPaperModel *)model{ self.lblYear.text = model.paperYear; self.lblProvince.text = model.paperProvince; self.lblTitle.text = model.paperTitle; } @end
3.5 由於剛自定義的Cell的窗口高度為88,所以設置行高為88
/** 3、設置行的高度 */ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 88.0f; }
4、返回指定的行,由於是自定義的Cell,所以此處需要返回WPaperCell,首先導入 #import "WPaperCell.h",然后設置,這里有兩種設置方式。
設置方式1:
/** 4、返回指定的 row 的 cell */ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // 1. cell標識符,使cell能夠重用 static NSString *paperCell = @"paperCell"; // 2. 注冊自定義Cell的到TableView中,並設置cell標識符為paperCell static BOOL isRegNib = NO; if (!isRegNib) { [tableView registerNib:[UINib nibWithNibName:@"WPaperCell" bundle:nil] forCellReuseIdentifier:paperCell]; isRegNib = YES; } // 3. 從TableView中獲取標識符為paperCell的Cell WPaperCell *cell = [tableView dequeueReusableCellWithIdentifier:paperCell]; // 4. 設置單元格屬性 [cell setupCell:_paperList[indexPath.row]]; return cell; }
設置方式2:
/** 4、返回指定的 row 的 cell */ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // 1. cell標示符,使cell能夠重用 static NSString *paperCell = @"paperCell"; // 2. 從TableView中獲取標示符為paperCell的Cell WPaperCell *cell = (WPaperCell *)[tableView dequeueReusableCellWithIdentifier:paperCell]; // 如果 cell = nil , 則表示 tableView 中沒有可用的閑置cell if(cell == nil){ // 3. 把 WPaperCell.xib 放入數組中 NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"WPaperCell" owner:self options:nil] ; // 獲取nib中的第一個對象 for (id oneObject in nib){ // 判斷獲取的對象是否為自定義cell if ([oneObject isKindOfClass:[WPaperCell class]]){ // 4. 修改 cell 對象屬性 cell = [(WPaperCell *)oneObject initWithStyle:UITableViewCellStyleDefault reuseIdentifier:paperCell]; } } } // 5. 設置單元格屬性 [cell setupCell:_paperList[indexPath.row]]; return cell; }
5、點擊單元格時,輸出省份,代碼如下:
/** 5、點擊單元格時的處理 */ -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ WPaperModel *paperModel = _paperList[indexPath.row]; NSLog(@"paper province -> %@", paperModel.paperProvince); }
OK,大功告成,運行一下,看看效果:
代碼傳送門:CustomTableViewCell
著作權聲明:本文由 http://wzrong.cnblogs.com 或者 http://iostour.diandian.com 原創,歡迎轉載分享。 請尊重作者勞動,轉載時保留該聲明和作者博客鏈接,謝謝!
原創文章,如需轉載請注明出處,謝謝!
歡迎訪問本人技術微博 @iOS之旅 相互交流,共同學習,共同進步!
歡迎訪問本人微博 @衛志榮