您所在的位置:小祥子 » 编程 » IOS » 正文

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

时间:2015-05-28 编辑:吃唐僧肉的小悟空 来源:本站整理

  [注意]转载时请注明出处博客园-吃唐僧肉的小悟空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

 //
 //  KZCar.h
 //  UI基础-06-05-19
 //
 //  Created by hukezhu on 15/5/20.
 //
 //
 
 #import <Foundation/Foundation.h>
 
 @interface KZCar : NSObject
 
 /**
  *  声明图片属性
  */
 @property (nonatomic,copy) NSString *icon;
 
 /**
  *  声明名称属性
  */
 @property (nonatomic,copy) NSString *name;
 
 
 -(instancetype)initWithDict:(NSDictionary *)dict;
 
 +(instancetype)carWithDict:(NSDictionary *)dict;
 
 +(NSArray *)carsWithDict:(NSArray *)dictarray;
 @end

KZCar.m

 //
 //  KZCar.m
 //  UI基础-06-05-19
 //
 //  Created by hukezhu on 15/5/20.
 //
 //
 
 #import "KZCar.h"
 
 @implementation KZCar
 
 -(instancetype)initWithDict:(NSDictionary *)dict{
 
     if (self = [super init]) {
         //使用KVC
         [self setValuesForKeysWithDictionary:dict];
     }
     return  self;
 }
 
 
 +(instancetype)carWithDict:(NSDictionary *)dict{
 
     return [[self alloc]initWithDict:dict];
 }
 
 //此处是里面的汽车数据模型,分析汽车数组转化的时候,发现此处只需要传入一个数组即可
 +(NSArray *)carsWithDict:(NSArray *)dictarray{
 
     
     NSMutableArray *tempArray = [NSMutableArray array];
     for (NSDictionary *dict in dictarray) {
         KZCar *car = [KZCar carWithDict:dict];
         [tempArray addObject:car];
     }
     return tempArray;
 }
 @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
 //
 //  KZCarGroup.m
 //  UI基础-06-05-19
 //
 //  Created by hukezhu on 15/5/20.
 //
 //
 
 #import "KZCarGroup.h"
 #import "KZCar.h"
 
 @implementation KZCarGroup
 -(instancetype)initWithDict:(NSDictionary *)dict{
 
     if (self = [super init]) {
         _title = dict[@"title"];
         
         //将字典中的数组cars取出来
         NSArray *array = dict[@"cars"];
         _cars = [KZCar carsWithDict:array];
     }
     return self;
 }
 
 +(instancetype)carGroupWithDict:(NSDictionary *)dict{
 
     return [[self alloc]initWithDict:dict];
 }
 
 +(NSArray *)carGroups{
 
 
     NSString *path = [[NSBundle mainBundle]pathForResource:@"cars_total" ofType:@"plist"];
     NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
     
     NSMutableArray *tempArray = [NSMutableArray array];
     for (NSDictionary *dict in dictArray) {
         KZCarGroup *carGroup = [KZCarGroup carGroupWithDict:dict];
         [tempArray addObject:carGroup];
     }
     return tempArray;
 }
 @end


ViewController.m

 //
 //  ViewController.m
 //  05-car多数据
 //
 //  Created by hukezhu on 15/5/20.
 //
 
 
 
 
 #import "ViewController.h"
 #import "KZCarGroup.h"
 #import "KZCar.h"
 
 @interface ViewController ()<UITableViewDataSource>
 
 @property (weak, nonatomic) IBOutlet UITableView *tableView;
 
 
 
 @property(nonatomic,strong)NSArray *cars;
 @end
 
 @implementation ViewController
 
 - (void)viewDidLoad {
     [super viewDidLoad];
     
     self.tableView.dataSource = self;
     NSLog(@"%@",self.cars);
 
 }
 #pragma mark -数据源方法
 /**
  *  返回一共有多少组
 
  */
 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
 
     return self.cars.count;
 }
 
 /**
  *  返回每一组有多少行
  *
  */
 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
 
     KZCarGroup *carGroup = self.cars[section];
     return carGroup.cars.count;
 }
 
 /**
  *  返回每行显示什么样的数据
  *
  */
 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
 
     NSString *identity = @"yes";
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identity ];
     
     if (cell == nil) {
         cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identity];
     }
     //取出组模型
     KZCarGroup *carGroup = self.cars[indexPath.section];
     //取出行模型
     KZCar *car = carGroup.cars[indexPath.row];
     
     cell.imageView.image = [UIImage imageNamed:car.icon];
     cell.textLabel.text = car.name;
     return cell;
 }
 
 
 /**
  *  设置头部biaoti
  *
  */
 -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
 
     //取出组模型
     KZCarGroup *carGroup = self.cars[section];
     return carGroup.title;
     
 }
 
 /**
  *  设置尾部描述
  *
  */
 -(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
 
     //取出组模型
     KZCarGroup *carGroup = self.cars[section];
     return carGroup.title;
     
 }
 /**
  *  懒加载数据
  *
  */
 -(NSArray *)cars{
 
     if (_cars == nil) {
         _cars = [KZCarGroup carGroups];
     }
     return _cars;
 }
 @end
 
关键词:Table