// loadView 加载表视图
- (void)loadView
{
// 1. 创建 tableView
UITableView *tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:(UITableViewStyleGrouped)];
// 2. 设置属性 分割线样式、 分割线颜色、 行高、 表头视图、表尾视图 、 代理、 数据源 等
// 分割线样式
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
// 分割线颜色
tableView.separatorColor = [UIColor redColor];
// 行高
tableView.rowHeight = 200;
// 设置代理 和 数据源
tableView.delegate = self; // 代理作用: 辅助外观,检测用户交互
tableView.dataSource = self; // 数据源作用: 提供数据,加载单元格
// 表视图 表头 headerView
CGFloat width = tableView.frame.size.width;
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:(CGRectMake(0, 0, width, 137))];
scrollView.contentSize = CGSizeMake(3 * width, 137);
scrollView.pagingEnabled = YES;
for (int i = 1; i < 4; i++) {
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"head_pic%d.jpg", i]];
CGFloat x = (i - 1) * width;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:(CGRectMake(x, 0, width, 137))];
imageView.image = image;
[scrollView addSubview:imageView];
[imageView release];
[image release];
}
// 把scrollView 设置为表视图的 表头视图
tableView.tableHeaderView = scrollView;
UIScrollView *scrollView2 = [[UIScrollView alloc] initWithFrame:(CGRectMake(0, 0, width, 137))];
scrollView2.contentSize = CGSizeMake(3 * width, 137);
scrollView2.pagingEnabled = YES;
for (int i = 1; i < 4; i++) {
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"head_pic%d.jpg", i]];
CGFloat x = (i - 1) * width;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:(CGRectMake(x, 0, width, 137))];
imageView.image = image;
[scrollView2 addSubview:imageView];
[imageView release];
[image release];
}
// 表尾视图
tableView.tableFooterView = scrollView2;
[scrollView2 release];
[scrollView release];
// 3. 赋值为 controller 根视图
self.view = tableView;
// 4. 释放
[tableView release];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark-
#pragma mark 数据源方法
// 返回分区数 分区数默认为1
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2; // 表示: 表视图中有两个分区
}
// 设置分区头标题
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == 0) {
return @"分区一";
} else
{
return @"分区二";
}
}
// 设置分区 右竖排索引
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return @[@"A", @"B"];
}
// 设置分区 区头高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 100;
}
// 自定义分区 区头
/*
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIImageView *imageView = [[[UIImageView alloc] initWithFrame:(CGRectMake(0, 0, 0, 137))] autorelease];
imageView.image = [UIImage imageNamed:@"head_pic1.jpg"];
return imageView;
}
*/
// 返回每个分区中 行数 | *必须实现
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10; // 每个分区中 有 10 行
}
static int count = 0;
// 加载单元格 方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 重用机制
// 表视图的重用机制,主要是通过一个重用队列来完成的。
// 1. 单元格的重用标识符
static NSString *identifier = @"cell1";
// 2. 创建单元格时首先去 表视图的 重用队列里 根据标识符 查找是否有可重用 单元格
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
// 3. 如果没有可重用单元格, 创建新的单元格
if (cell == nil) {
// 注意: 要加上重用标识符
cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:identifier];
NSLog(@" %d", ++count);
}
// 4. 设置单元格
cell.textLabel.text = [NSString stringWithFormat:@" %ld %ld", indexPath.section, indexPath.row];
// 5. 返回
return cell;
/*
// 1. 创建 单元格
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:nil];
NSLog(@" %d", ++count);
// 2. 设置单元格
cell.textLabel.text = [NSString stringWithFormat:@"第%ld分区 第%ld行", indexPath.section, indexPath.row];
// 3. 返回单元格
return cell;
*/
}
@interface ContactViewController () <UITableViewDataSource, UITableViewDelegate>
// 字典储存联系人
@property (nonatomic,retain) NSMutableDictionary *contactDic;
// 数组存储有序键值
@property (nonatomic,retain) NSMutableArray *keyArray;
@end
@implementation ContactViewController
- (void)dealloc
{
[_contactDic release];
[_keyArray release];
[super dealloc];
}
- (void)loadView
{
UITableView *tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:(UITableViewStylePlain)];
tableView.delegate = self;
tableView.dataSource = self;
tableView.rowHeight = 110;
self.view = tableView;
[tableView release];
}
// 设置数据
- (void)setData
{
// 1. 文件路径
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Class25ContactList" ofType:@"plist"];
// 2. 根据文件路径创建字典
// 给字典赋值
self.contactDic = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
// 3. 给数组赋值
self.keyArray = [[[_contactDic allKeys] sortedArrayUsingSelector:@selector(compare:)] mutableCopy];
}
- (void)viewDidLoad {
[super viewDidLoad];
// 加载数据
[self setData];
// controller 自带一个编辑按钮 editButtonItem
// 该按钮点击时,触发 setEditing:方法, 切换编辑状态
self.navigationItem.rightBarButtonItem = self.editButtonItem;
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark-
#pragma mark indexPath - 数据方法
// 返回indexPath对应的联系人
- (NSDictionary *)contactWithIndexPath:(NSIndexPath *)indexPath
{
return _contactDic[_keyArray[indexPath.section]][indexPath.row];
}
// 返回indexPaht 对应的联系人组
- (NSMutableArray *)groupWithIndexPath:(NSIndexPath *)indexPath
{
return _contactDic[_keyArray[indexPath.section]];
}
// 返回indexPath 对应的组名
- (NSString *)groupNameWithIndexPath:(NSIndexPath *)indexPath
{
return _keyArray[indexPath.section];
}
#pragma mark-
#pragma mark 数据源信息
// 分区头标题
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return _keyArray[section];
}
// 分区索引
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return _keyArray;
}
// 分区数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [_keyArray count];
}
// 分区中行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_contactDic[_keyArray[section]] count];
}
// 加载单元格
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1. 重用标识符
static NSString *cellIdentifier = @"cell1";
// 2. 重用队列中查找获取单元格
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
// MRC 下,cell 创建的时候要加上 autolease,为了防止内存泄露。
cell = [[[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:cellIdentifier] autorelease];
}
// 3. 设置单元格
NSDictionary *contact = [self contactWithIndexPath:indexPath];
NSString *name = contact[@"name"];
NSString *phone = contact[@"phoneNumber"];
cell.textLabel.text = name;
cell.detailTextLabel.text = phone;
// 4. 返回
return cell;
}
#pragma mark-
#pragma mark tableView 编辑
/*
表视图编辑的步骤:
1. 把表视图设置为可编辑状态,setEditing方法
2. 哪一行哪个分区可以被编辑
3. 设置编辑的类型: 删除 还是 插入
4. 提交编辑,注意:需要先操作数据源,再操作UI
*/
// 1. 把表视图设置为可编辑状态,
//
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
// 1. 需要把controller 设置为编辑状态,通过编辑按钮,显示编辑控件
[super setEditing:editing animated:YES];
// 2. 把tableView 设置为可编辑状态
[(UITableView *)self.view setEditing:editing animated:YES];
}
// 2. 哪行可以编辑
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// if (indexPath.row < 5) {
// return YES;
// } else
// return NO;
return YES;
// 默认是所有行都可以被编辑,默认返回值为YES
}
// 3. 指定编辑样式
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row < 2) {
return UITableViewCellEditingStyleDelete;
} else{
return UITableViewCellEditingStyleInsert;
}
}
// 4. 进行编辑
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// 注意: 所有的编辑操作必须写在[tableView beginUpdates] 和 [tableView endUpdaates],里面。
[tableView beginUpdates]; // 开始编辑
// 判断当前编辑样式
if (editingStyle == UITableViewCellEditingStyleDelete) {
// 删除操作,先删除数据源,再删除UI
} else { // 插入操作, 先插入数据源, 再插入UI
}
[tableView endUpdates]; // 结束编辑
}
@end