1.UItableViewController 继承于UIViewController,有特有的初始化方法initwithStyle
2.一般不需要重新写loadView方法因为系统已经为我们创建了一个TableView,并且遵循了dataSource和delegate协议,一些常用的方法也帮我们写好了(布局移动删除)
3.self.view和self.tableview是同一个图层,但是我们使用时候可以给self.tableView发送TableView的消息,前者不能;
首先:我们从一个plist文件中读取数据并展示在UITableViewController的TableView上面,数据的本地化读取在后面会有更多使用;数据解析方法也会有介绍.
先看效果图
- (void)viewDidLoad {
[super viewDidLoad];
// 注册cell 利用重用池机制
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"reuseIdentifier" ];
self.tableView.rowHeight = 80;
// 从 plist 文件得到数据(自定义方法记住要执行)
>
[self getData];
}
plist文件层级关系展示
- (void)getData
{
// 1: 找到plist路径
NSString *pathData = [[NSBundle mainBundle] pathForResource:@"MyClass" ofType:@"plist"];
// 2: 接收最外层的的字典
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithContentsOfFile:pathData];
// 3: 把我们定义的接收数据的数组和字典开辟创建出来
self.dataDic = [[NSMutableDictionary alloc] initWithCapacity:26];
self.dataArray = [NSMutableArray arrayWithCapacity:26];
// 4: 把大字典数据取出来,键值Key作为区名放入dataArray 并且和 Student (Model) 类建立联系
for (NSString *key in dic)
{
// 把遍历的Key到数据源数组
[self.dataArray addObject:key];
// 创建一个可变的数组存放每一次对应的Student实例对象
NSMutableArray *arrayStu = [NSMutableArray arrayWithCapacity:10];
for (NSDictionary *dicTemp in dic[key])
{
Student *stu = [Student new];
[stu setValuesForKeysWithDictionary:dicTemp];
// 把对应的区的人放到相应的数组中
[arrayStu addObject:stu];
}
// 把每一个区(key)和其对应的数组(存放的是该区的实例对象)作为键值对存在字典里面
[self.dataDic setObject:arrayStu forKey:key];
}
// 把数据源数组元素排序一下(目的:是作为索引时候有顺序)
[self.dataArray sortUsingSelector:@selector(compare:)];
NSLog(@"检测数据2: %@",self.dataDic);
}
// self.dataArray 中有几个元素就有几个分区
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.dataArray.count;
}
// 对应分区中有几个人 (现根据分区找到key值根据key值找到对应的数组 数组的元素个数就是没个区行数)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.dataDic[self.dataArray[section]] count];
}
建立cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath];
cell.backgroundColor = [UIColor colorWithRed:(arc4random()%345)/346.0 green:(arc4random()%345)/346.0 blue:(arc4random()%345)/346.0 alpha: 0.5];
// 找到每一行(row)对应的数据 用Student的实例对象接收
Student *stu = self.dataDic[self.dataArray[indexPath.section]][indexPath.row];
// 把数据显示在cell再带的label上面 设置居中对齐
cell.textLabel.text = [NSString stringWithFormat:@"%@-(%@)-%@",stu.name,stu.gender,stu.phoneNumber];
cell.textLabel.textAlignment = 1;
// 显示头像(自带的imageView尺寸只读所以自己建一个UiiamgeView放置图片)
UIImageView *myImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, tableView.rowHeight-10, tableView.rowHeight - 10)];
myImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",stu.name]];
// 还可以把图像设置成圆形
myImage.layer.masksToBounds = YES;
myImage.layer.cornerRadius = (tableView.rowHeight - 10)/2.0;
[cell addSubview:myImage];
return cell;
}
// 每一个区的标题也就是A.B.C.......
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
// 对应self.dataArray的元素
return self.dataArray[section];
}
// 设置右侧的索引
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
// 其实就我们数据源组存的东西
return self.dataArray;
}
上面几步就完成了页面的简单搭建实现了图形的效果,下面是一些简单的操作
首先打开编辑状态:
//可以在Button或者导航栏按钮的方法中点击打开(这个在ViewDidLoad)方法写就行
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"编辑" style:(UIBarButtonItemStyleDone) target:self action:@selector(rightAction:)];
// 第一步: 打开编辑状态
- (void)rightAction:(UIBarButtonItem *)sender
{
if ([sender.title isEqualToString:@"编辑"])
{
sender.title = @"完成";
[self.tableView setEditing:1 animated:1];
}else
{
sender.title = @"编辑";
[self.tableView setEditing:0 animated:0];
}
}
// 第二步: 指定哪些路径可以被编辑 (这里是第一个区不让编辑)
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1)
{
return 0;
}
return 1;
}
// 第三步: 指定编辑样式 (这里是第四区的cell可以添加其他cell可以删除)
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 4)
{
/*
UITableViewCellEditingStyleNone ,
UITableViewCellEditingStyleDelete 删除,
UITableViewCellEditingStyleInsert 增加
*/
return UITableViewCellEditingStyleInsert;
}
return UITableViewCellEditingStyleDelete;
}
// 第四步: 完成编辑(删除添加)
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// 删除
if (editingStyle == UITableViewCellEditingStyleDelete)
{
NSMutableArray *array = self.dataDic[self.dataArray[indexPath.section]];
>// 如果当前分组只有一个人,分组也删除
>
if (array.count == 1)
{
// 直接删除分组
[self.dataDic removeObjectForKey:self.dataArray[indexPath.section]];
// 删除快速索引里面对应的索引
[self.dataArray removeObjectAtIndex:indexPath.section];
// 更新UI(第一种方法)
NSIndexSet *set = [NSIndexSet indexSetWithIndex:indexPath.section];
// 删除分区
[_tableview deleteSections:set withRowAnimation:(UITableViewRowAnimationLeft)];
// 更新UI(第二种重新加载一下)
// [_tabelview reloadData];
}
[self.dataDic[self.dataArray[indexPath.section]]removeObjectAtIndex:indexPath.row];
// 更新UI
[_tabelview deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:(UITableViewRowAnimationLeft)];
}
// 增加 (这就用个假数据)
Model *temp = [Model new];
temp.name = @"詹姆斯";
temp.gender = @"男";
temp.phoneNumber = @"15565257587有事没事常联系";
// 在对应的原(字典中对应的)数组中加入
[self.dataDic[self.dataArray[indexPath.section]]insertObject:temp atIndex:indexPath.row + 1];
// 找到添加的位置
NSIndexPath *new = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:indexPath.section];
// 更新UI
[_tabelview insertRowsAtIndexPaths:@[new] withRowAnimation:(UITableViewRowAnimationLeft)];
}
// 移动 (上面的一二两步方法有了之后就可以执行移动方法)
// 第三步: 完成移动
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
// 根据原路径找到对应分组
NSMutableArray *array = self.dataDic[self.dataArray[sourceIndexPath.section]];
>
// 找到对应的行数
Model *model = array[sourceIndexPath.row];
// 先删除
[array removeObjectAtIndex:sourceIndexPath.row];
// 添加到目的路径
[array insertObject:model atIndex:destinationIndexPath.row];
}
另外:
// section中的数据,跨区一般是不允许的
// 检测跨区移动 (使之只能在一个区移动)
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
// 如果计划目的路径分区和原路径分区相同,直接返回目的路径
if (sourceIndexPath.section == proposedDestinationIndexPath.section)
{
return proposedDestinationIndexPath;
}
return sourceIndexPath;
}