黑马程序员_iOS 的高级控件之UITableView基本应用

来源:互联网 发布:拙心网络米汤 编辑:程序博客网 时间:2024/06/05 12:01
iOS,Android,Java培训,期待与您的交流
iOS应用开发的一项内容就是用户界面的开发。不管应用程序实际包含的逻辑有多复杂,如果这个应用程序没有提供友好的图形用户界面,將很难吸引用户。作为一个程序设计者,必须优先考虑用户的感受,一定要让用户感到爽,这个应用程序才有价值。
1    UITableView的基本概念
表视图是iOS开发中使用最频繁的视图。一般情况下,我们都会选择以表的形式来展现数据,比如通讯录和频道列表等。在表视图中,分节,分组和索引等功能使我们展示的数据看起来更规整、更有调理。更令人兴奋的是,表视图还可以利用细节展示等功能多层次地展示数据。
以上图为例,说明表视图的几个概念。
1、节头:节的头,描述节的信息,比如图中的广东,湖南,广东2都是节头
2、单元格(cell):它是表视图中每一行,比如图中的广州那一行,长沙那一行
3、节脚:节的最后一部分,用于描述节的的信息和声明,文章居中对齐,比如广东好,湖南也好
4、节(section):节是由节头,单元格,节脚组成。节可以没有节头和节脚。上图的表视图由三个节组成,表视图可以由任意个节组成。
2    UITableView的基本用法
表视图是將数据一行一行地显示出来,它是通过数据源代理获得数据的。数据源代理对象应该实现UITableViewDataSource协议的三个方法:
1、- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; 指定表视图有几个节(section)
2、- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; 表视图的第section个节有多少个单元格
3、- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; 指定表视图的第section个节第row行的UITableViewCell
我们首先不显示节头和节脚。 每个省的城市保存在一个NSArray中,这三个省又组成一个数组。
  - (void)viewDidLoad{    [super viewDidLoad];        // 1.添加tableView    UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];    tableView.dataSource = self;   //设置该表视图的数据代理对象    [self.view addSubview:tableView];        _allCities = @[                   @[@"广州", @"深圳", @"梅州"],                   @[@"长沙", @"益阳"],                   @[@"武汉", @"黄冈"],    ];}
现在实现UITableViewDataSource协议的三个方法。
  #pragma mark 一共有多少组(section == 区域\组)- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    return _allCities.count;}#pragma mark 第section组一共有多少行- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{        // 1.取得第section组的所有城市    NSArray *sectionCities = _allCities[section];        // 2.第section组城市的个数    return sectionCities.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];        //1、取出该cell的数据    NSString *text = _allCities[indexPath.section][indexPath.row];          // 2.展示文字数据    cell.textLabel.text = text;    return cell;}
运行结果如下图所示。
3    带有节头节脚的UITableView
如果想显示节头节脚,需要实现实现UITableViewDataSource协议的另外两个方法。
1、- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; 指定第section分区的头部标题
2、- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section; 指定第section分区的头脚标题
为了保存每个section的节头和节脚,可以用NSDictionary保存每个省份的信息,所有的省份信息又组成一个NSArray。
  // 省份字典中用到的key#define kHeader @"header" // 头部标题对应的key#define kFooter @"footer" // 尾部标题对应的key#define kCities @"cities" // 城市数组对应的key@interface MJViewController () {    NSArray *_allProvinces; // 所有的省份}@end@implementation MJViewController- (void)viewDidLoad{    [super viewDidLoad];        // 1.添加tableView    UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];    tableView.dataSource = self;    [self.view addSubview:tableView];        // 2.初始化数据    _allProvinces = @[                                            @{                          kHeader : @"广东",                          kFooter : @"广东好",                          kCities : @[@"广州", @"深圳", @"梅州"]                      },                                            @{                          kHeader : @"湖南",                          kFooter : @"湖南也好",                          kCities : @[@"长沙", @"益阳"]                       },                                            @{                          kHeader : @"湖北",                          kFooter : @"湖北更好",                          kCities : @[@"武汉", @"黄冈"]                          }        ];}
为了展示节头节脚,应该实现UITableViewDataSource协议的五个方法。
  #pragma mark - 数据源方法#pragma mark 一共有多少组(section == 区域\组)- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    return _allProvinces.count;}#pragma mark 第section组一共有多少行- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    // 1.取得第section组的省份    NSDictionary *province = _allProvinces[section];        // 2.取得省份里面的城市数组    NSArray *cities = province[kCities];        return cities.count;}#pragma mark 返回每一行显示的内容(每一行显示怎样的cell)- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];    // 1.取出第section组第row行的文字数据    // 取出第section组的省份 中 城市数组里面 第 row行的 数据        NSDictionary *province = _allProvinces[indexPath.section];    NSArray *cities = province[kCities];        NSString *text = cities[indexPath.row];        // 2.展示文字数据    cell.textLabel.text = text;    return cell;}#pragma mark 第section组显示的头部标题- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{        NSDictionary *province = _allProvinces[section];        return province[kHeader];}#pragma mark 第section组显示的尾部标题- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{       return _allProvinces[section][kFooter];}
运行结果如下图所示。
4    使用模型保存数据
用NSArray和NSDictionary保存数据虽然很方便,但是不够面向对象。我们可以把省份抽象成一个类,节头节脚以及城市是该类的属性,并且提供一个类方法创建实例。该类的声明和定义如下。
  //Province.h@interface Province : NSObject// UI控件用weak,NSString用copy,其他对象一般用strong@property (nonatomic, copy) NSString *header;@property (nonatomic, copy) NSString *footer;@property (nonatomic, strong) NSArray *citites;+ (id)provinceWithHeader:(NSString *)header footer:(NSString *)footer cities:(NSArray *)cities;@end//Province.m+ (id)provinceWithHeader:(NSString *)header footer:(NSString *)footer cities:(NSArray *)cities{    Province *p = [[Province alloc] init];    p.header = header;    p.footer = footer;    p.citites = cities;    return p;}
为了展示节头节脚,应该实现UITableViewDataSource协议的五个方法。
  - (void)viewDidLoad{    [super viewDidLoad];        // 1.添加tableView    UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];    tableView.dataSource = self;    [self.view addSubview:tableView];        // 2.初始化数据    _allProvinces = @[        [Province provinceWithHeader:@"广东" footer:@"广东好" cities:@[@"广州", @"深圳"]],                [Province provinceWithHeader:@"湖南" footer:@"湖南也好" cities:@[@"长沙"]],                [Province provinceWithHeader:@"广东2" footer:@"广东好" cities:@[@"广州", @"深圳"]],                [Province provinceWithHeader:@"湖南2" footer:@"湖南也好" cities:@[@"长沙"]]    ];}#pragma mark - 数据源方法#pragma mark 一共有多少组(section == 区域\组)- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    return _allProvinces.count;}#pragma mark 第section组一共有多少行- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    // 1.取得第section组的省份    Province *province = _allProvinces[section];        // 2.取得省份里面的城市数组    return province.citites.count;}#pragma mark 返回每一行显示的内容(每一行显示怎样的cell)- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];        Province *province = _allProvinces[indexPath.section];        // 展示文字数据    cell.textLabel.text = province.citites[indexPath.row];        return cell;}#pragma mark 第section组显示的头部标题- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{    Province *province = _allProvinces[section];        return [province header];}#pragma mark 第section组显示的尾部标题- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{    return [_allProvinces[section] footer];}
5    总结
UITableView是严格遵循MVC模式的控件,开发人员只需要提供数据,提供数据必须实现UITableViewDataSource协议的三个方法,并且可以自定义cell的显示样式。
iOS,Android,Java培训,期待与您的交流
0 0