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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值