[注意]轉載時請註明出處博客園-吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/數組
在IOS中,實現表格展現數據,最經常使用的作法就是使用UITableView.ide
@interface UITableView : UIScrollView <NSCoding>
UITableView繼承自UIScrollView,因此支持垂直滾動,並且性能極佳(這個會在之後提到,支持重用cell)性能
UITableView有兩種樣式:分組和不分組ui
分組:UITableViewStyleGroupedatom
不分組:UITableViewStylePlainspa
@property (nonatomic, readonly) UITableViewStyle style; @property (nonatomic, assign) id <UITableViewDataSource> dataSource; @property (nonatomic, assign) id <UITableViewDelegate> delegate; @property (nonatomic) CGFloat rowHeight; // will return the default value if unset
1.UITableView須要一個數據源(dataSource)來顯示數據(如上面代碼)3d
2.UITableView會向數據源查詢一共有多少行數據以及每一行顯示什麼數據等code
@protocol UITableViewDataSource<NSObject> @required - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; // Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier: // Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls) - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; @optional - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; // Default is 1 if not implemented - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; // fixed font style. use custom view (UILabel) if you want something different - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section; // Editing // Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable. - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath; // Moving/reordering // Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath: - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath; // Index - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView; // return list of section titles to display in section index view (e.g. "ABCD...Z#") - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index; // tell table which section corresponds to section title/index (e.g. "B",1)) // Data manipulation - insert and delete support // After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change // Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath; // Data manipulation - reorder / moving support - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath; @end
3.沒有設置數據元的UITableView只是一個空的殼子,不會展現任何數據對象
4.上面代碼是UITableViewDataSource協議的,凡是遵照UITableViewDataSource協議的OC對象,均可以是UITableView的數據源,此處咱們通常選擇控制器爲數據源.blog
因此總結一下使用UITableView展現數據的步驟:
UITableViewDataSource協議中必需要實現的方法:
@required //每一組有多少行 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; // Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier: // Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls) //每一行顯示什麼樣的內容 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
下面這個方法不是必需要實現的,不實現默認就是1組
//一共有多少組 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; //這個方法不是必需要實現的,若是不實現,就默認是一組
下面經過一個小例子來演示UITableView的使用
下圖是應用代碼結構及plist文件截圖:
此處的plist文件相對於前面文章介紹的比較複雜,此處是字典中又包含字典,因此使用的字典轉模型的方法與以前也有所不一樣.首先要將裏面的字典先轉化爲模型,再轉化外面的.
上圖中標註的KZCar是汽車數據模型
上圖中標註的KZCarGroup是汽車組的數據模型,下面附上代碼,其中尤爲要注意,這個複雜的數據模型的轉化過程.
KZCar.h
1 // 2 // KZCar.h 3 // UI基礎-06-05-19 4 // 5 // Created by hukezhu on 15/5/20. 6 // 7 // 8 9 #import <Foundation/Foundation.h> 10 11 @interface KZCar : NSObject 12 13 /** 14 * 聲明圖片屬性 15 */ 16 @property (nonatomic,copy) NSString *icon; 17 18 /** 19 * 聲明名稱屬性 20 */ 21 @property (nonatomic,copy) NSString *name; 22 23 24 -(instancetype)initWithDict:(NSDictionary *)dict; 25 26 +(instancetype)carWithDict:(NSDictionary *)dict; 27 28 +(NSArray *)carsWithDict:(NSArray *)dictarray; 29 @end
KZCar.m
1 // 2 // KZCar.m 3 // UI基礎-06-05-19 4 // 5 // Created by hukezhu on 15/5/20. 6 // 7 // 8 9 #import "KZCar.h" 10 11 @implementation KZCar 12 13 -(instancetype)initWithDict:(NSDictionary *)dict{ 14 15 if (self = [super init]) { 16 //使用KVC 17 [self setValuesForKeysWithDictionary:dict]; 18 } 19 return self; 20 } 21 22 23 +(instancetype)carWithDict:(NSDictionary *)dict{ 24 25 return [[self alloc]initWithDict:dict]; 26 } 27 28 //此處是裏面的汽車數據模型,分析汽車數組轉化的時候,發現此處只須要傳入一個數組便可 29 +(NSArray *)carsWithDict:(NSArray *)dictarray{ 30 31 32 NSMutableArray *tempArray = [NSMutableArray array]; 33 for (NSDictionary *dict in dictarray) { 34 KZCar *car = [KZCar carWithDict:dict]; 35 [tempArray addObject:car]; 36 } 37 return tempArray; 38 } 39 @end
KZCarGroup.h
// // KZCarGroup.h // UI基礎-06-05-19 // // Created by hukezhu on 15/5/20. // // #import <Foundation/Foundation.h> @interface KZCarGroup : NSObject /** * 聲明一個汽車的屬性 */ @property (nonatomic,strong)NSArray *cars; /** * 聲明一個標題的屬性 */ @property (nonatomic,copy)NSString *title; -(instancetype)initWithDict:(NSDictionary *)dict; +(instancetype)carGroupWithDict:(NSDictionary *)dict; +(NSArray *)carGroups; @end
KZCarGroup.m
1 // 2 // KZCarGroup.m 3 // UI基礎-06-05-19 4 // 5 // Created by hukezhu on 15/5/20. 6 // 7 // 8 9 #import "KZCarGroup.h" 10 #import "KZCar.h" 11 12 @implementation KZCarGroup 13 -(instancetype)initWithDict:(NSDictionary *)dict{ 14 15 if (self = [super init]) { 16 _title = dict[@"title"]; 17 18 //將字典中的數組cars取出來 19 NSArray *array = dict[@"cars"]; 20 _cars = [KZCar carsWithDict:array]; 21 } 22 return self; 23 } 24 25 +(instancetype)carGroupWithDict:(NSDictionary *)dict{ 26 27 return [[self alloc]initWithDict:dict]; 28 } 29 30 +(NSArray *)carGroups{ 31 32 33 NSString *path = [[NSBundle mainBundle]pathForResource:@"cars_total" ofType:@"plist"]; 34 NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; 35 36 NSMutableArray *tempArray = [NSMutableArray array]; 37 for (NSDictionary *dict in dictArray) { 38 KZCarGroup *carGroup = [KZCarGroup carGroupWithDict:dict]; 39 [tempArray addObject:carGroup]; 40 } 41 return tempArray; 42 } 43 @end
ViewController.m
1 // 2 // ViewController.m 3 // 05-car多數據 4 // 5 // Created by hukezhu on 15/5/20. 6 // 7 8 9 10 11 #import "ViewController.h" 12 #import "KZCarGroup.h" 13 #import "KZCar.h" 14 15 @interface ViewController ()<UITableViewDataSource> 16 17 @property (weak, nonatomic) IBOutlet UITableView *tableView; 18 19 20 21 @property(nonatomic,strong)NSArray *cars; 22 @end 23 24 @implementation ViewController 25 26 - (void)viewDidLoad { 27 [super viewDidLoad]; 28 29 self.tableView.dataSource = self; 30 NSLog(@"%@",self.cars); 31 32 } 33 #pragma mark -數據源方法 34 /** 35 * 返回一共有多少組 36 37 */ 38 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 39 40 return self.cars.count; 41 } 42 43 /** 44 * 返回每一組有多少行 45 * 46 */ 47 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 48 49 KZCarGroup *carGroup = self.cars[section]; 50 return carGroup.cars.count; 51 } 52 53 /** 54 * 返回每行顯示什麼樣的數據 55 * 56 */ 57 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 58 59 NSString *identity = @"yes"; 60 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identity ]; 61 62 if (cell == nil) { 63 cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identity]; 64 } 65 //取出組模型 66 KZCarGroup *carGroup = self.cars[indexPath.section]; 67 //取出行模型 68 KZCar *car = carGroup.cars[indexPath.row]; 69 70 cell.imageView.image = [UIImage imageNamed:car.icon]; 71 cell.textLabel.text = car.name; 72 return cell; 73 } 74 75 76 /** 77 * 設置頭部biaoti 78 * 79 */ 80 -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ 81 82 //取出組模型 83 KZCarGroup *carGroup = self.cars[section]; 84 return carGroup.title; 85 86 } 87 88 /** 89 * 設置尾部描述 90 * 91 */ 92 -(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{ 93 94 //取出組模型 95 KZCarGroup *carGroup = self.cars[section]; 96 return carGroup.title; 97 98 } 99 /** 100 * 懶加載數據 101 * 102 */ 103 -(NSArray *)cars{ 104 105 if (_cars == nil) { 106 _cars = [KZCarGroup carGroups]; 107 } 108 return _cars; 109 } 110 @end