**舞榭歌臺(tái),風(fēng)流總被雨打風(fēng)吹去!**<由基拉>
1.UItableViewController 繼承于UIViewController,有特有的初始化方法initwithStyle
2.一般不需要重新寫loadView方法因?yàn)橄到y(tǒng)已經(jīng)為我們創(chuàng)建了一個(gè)TableView,并且遵循了dataSource和delegate協(xié)議,一些常用的方法也幫我們寫好了(布局移動(dòng)刪除)
3.self.view和self.tableview是同一個(gè)圖層,但是我們使用時(shí)候可以給self.tableView發(fā)送TableView的消息,前者不能;
首先:我們從一個(gè)plist文件中讀取數(shù)據(jù)并展示在UITableViewController的TableView上面,數(shù)據(jù)的本地化讀取在后面會(huì)有更多使用;數(shù)據(jù)解析方法也會(huì)有介紹.
先看效果圖
- (void)viewDidLoad {
[super viewDidLoad];
// 注冊(cè)cell 利用重用池機(jī)制
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"reuseIdentifier" ];
self.tableView.rowHeight = 80;
// 從 plist 文件得到數(shù)據(jù)(自定義方法記住要執(zhí)行)
>
[self getData];
}
plist文件層級(jí)關(guān)系展示
- (void)getData
{
// 1: 找到plist路徑
NSString *pathData = [[NSBundle mainBundle] pathForResource:@"MyClass" ofType:@"plist"];
// 2: 接收最外層的的字典
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithContentsOfFile:pathData];
// 3: 把我們定義的接收數(shù)據(jù)的數(shù)組和字典開辟創(chuàng)建出來(lái)
self.dataDic = [[NSMutableDictionary alloc] initWithCapacity:26];
self.dataArray = [NSMutableArray arrayWithCapacity:26];
// 4: 把大字典數(shù)據(jù)取出來(lái),鍵值Key作為區(qū)名放入dataArray 并且和 Student (Model) 類建立聯(lián)系
for (NSString *key in dic)
{
// 把遍歷的Key到數(shù)據(jù)源數(shù)組
[self.dataArray addObject:key];
// 創(chuàng)建一個(gè)可變的數(shù)組存放每一次對(duì)應(yīng)的Student實(shí)例對(duì)象
NSMutableArray *arrayStu = [NSMutableArray arrayWithCapacity:10];
for (NSDictionary *dicTemp in dic[key])
{
Student *stu = [Student new];
[stu setValuesForKeysWithDictionary:dicTemp];
// 把對(duì)應(yīng)的區(qū)的人放到相應(yīng)的數(shù)組中
[arrayStu addObject:stu];
}
// 把每一個(gè)區(qū)(key)和其對(duì)應(yīng)的數(shù)組(存放的是該區(qū)的實(shí)例對(duì)象)作為鍵值對(duì)存在字典里面
[self.dataDic setObject:arrayStu forKey:key];
}
// 把數(shù)據(jù)源數(shù)組元素排序一下(目的:是作為索引時(shí)候有順序)
[self.dataArray sortUsingSelector:@selector(compare:)];
NSLog(@"檢測(cè)數(shù)據(jù)2: %@",self.dataDic);
}
// self.dataArray 中有幾個(gè)元素就有幾個(gè)分區(qū)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.dataArray.count;
}
// 對(duì)應(yīng)分區(qū)中有幾個(gè)人 (現(xiàn)根據(jù)分區(qū)找到key值根據(jù)key值找到對(duì)應(yīng)的數(shù)組 數(shù)組的元素個(gè)數(shù)就是沒個(gè)區(qū)行數(shù))
- (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)對(duì)應(yīng)的數(shù)據(jù) 用Student的實(shí)例對(duì)象接收
Student *stu = self.dataDic[self.dataArray[indexPath.section]][indexPath.row];
// 把數(shù)據(jù)顯示在cell再帶的label上面 設(shè)置居中對(duì)齊
cell.textLabel.text = [NSString stringWithFormat:@"%@-(%@)-%@",stu.name,stu.gender,stu.phoneNumber];
cell.textLabel.textAlignment = 1;
// 顯示頭像(自帶的imageView尺寸只讀所以自己建一個(gè)UiiamgeView放置圖片)
UIImageView *myImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, tableView.rowHeight-10, tableView.rowHeight - 10)];
myImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",stu.name]];
// 還可以把圖像設(shè)置成圓形
myImage.layer.masksToBounds = YES;
myImage.layer.cornerRadius = (tableView.rowHeight - 10)/2.0;
[cell addSubview:myImage];
return cell;
}
// 每一個(gè)區(qū)的標(biāo)題也就是A.B.C.......
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
// 對(duì)應(yīng)self.dataArray的元素
return self.dataArray[section];
}
// 設(shè)置右側(cè)的索引
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
// 其實(shí)就我們數(shù)據(jù)源組存的東西
return self.dataArray;
}
上面幾步就完成了頁(yè)面的簡(jiǎn)單搭建實(shí)現(xiàn)了圖形的效果,下面是一些簡(jiǎn)單的操作
首先打開編輯狀態(tài):
//可以在Button或者導(dǎo)航欄按鈕的方法中點(diǎn)擊打開(這個(gè)在ViewDidLoad)方法寫就行
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"編輯" style:(UIBarButtonItemStyleDone) target:self action:@selector(rightAction:)];
// 第一步: 打開編輯狀態(tài)
- (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];
}
}
// 第二步: 指定哪些路徑可以被編輯 (這里是第一個(gè)區(qū)不讓編輯)
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1)
{
return 0;
}
return 1;
}
// 第三步: 指定編輯樣式 (這里是第四區(qū)的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]];
>// 如果當(dāng)前分組只有一個(gè)人,分組也刪除
>
if (array.count == 1)
{
// 直接刪除分組
[self.dataDic removeObjectForKey:self.dataArray[indexPath.section]];
// 刪除快速索引里面對(duì)應(yīng)的索引
[self.dataArray removeObjectAtIndex:indexPath.section];
// 更新UI(第一種方法)
NSIndexSet *set = [NSIndexSet indexSetWithIndex:indexPath.section];
// 刪除分區(qū)
[_tableview deleteSections:set withRowAnimation:(UITableViewRowAnimationLeft)];
// 更新UI(第二種重新加載一下)
// [_tabelview reloadData];
}
[self.dataDic[self.dataArray[indexPath.section]]removeObjectAtIndex:indexPath.row];
// 更新UI
[_tabelview deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:(UITableViewRowAnimationLeft)];
}
// 增加 (這就用個(gè)假數(shù)據(jù))
Model *temp = [Model new];
temp.name = @"詹姆斯";
temp.gender = @"男";
temp.phoneNumber = @"15565257587有事沒事常聯(lián)系";
// 在對(duì)應(yīng)的原(字典中對(duì)應(yīng)的)數(shù)組中加入
[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)];
}
// 移動(dòng) (上面的一二兩步方法有了之后就可以執(zhí)行移動(dòng)方法)
// 第三步: 完成移動(dòng)
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
// 根據(jù)原路徑找到對(duì)應(yīng)分組
NSMutableArray *array = self.dataDic[self.dataArray[sourceIndexPath.section]];
>
// 找到對(duì)應(yīng)的行數(shù)
Model *model = array[sourceIndexPath.row];
// 先刪除
[array removeObjectAtIndex:sourceIndexPath.row];
// 添加到目的路徑
[array insertObject:model atIndex:destinationIndexPath.row];
}
另外:
// section中的數(shù)據(jù),跨區(qū)一般是不允許的
// 檢測(cè)跨區(qū)移動(dòng) (使之只能在一個(gè)區(qū)移動(dòng))
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
// 如果計(jì)劃目的路徑分區(qū)和原路徑分區(qū)相同,直接返回目的路徑
if (sourceIndexPath.section == proposedDestinationIndexPath.section)
{
return proposedDestinationIndexPath;
}
return sourceIndexPath;
}