ios开发-UI-UITableView及一个小实例

  [注意]转载时请注明出处博客园-吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/

  在IOS中,实现表格展示数据,最常用的做法就是使用UITableView.

@interface UITableView : UIScrollView <NSCoding>

  UITableView继承自UIScrollView,所以支持垂直滚动,而且性能极佳(这个会在以后提到,支持重用cell)

  UITableView有两种样式:分组和不分组

    分组:UITableViewStyleGrouped

    不分组:UITableViewStylePlain

  

@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)来显示数据(如上面代码)

  2.UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等

    

@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的数据源,此处我们一般选择控制器为数据源.

  所以总结一下使用UITableView展示数据的步骤:

    • 遵守UITableViewDataSource协议
    • 设置控制器为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

 

 

 

posted @ 2015-05-28 09:43  吃唐僧肉的小悟空  阅读(1681)  评论(0编辑  收藏  举报