UITableView的一些属性

来源:互联网 发布:c2c电商市场份额 淘宝 编辑:程序博客网 时间:2024/04/29 00:53

UITableViewCell delete button 上有其它覆盖层  delete按钮

http://blog.csdn.net/meegomeego/article/details/16961547

//第三种可以

- (void)layoutSubviews

{

    [superlayoutSubviews];

    if (self.isEditing) {

        [selfsendSubviewToBack:self.contentView];

    }

    

}




1.基本概念 

UITableViewStylePlain

 //Plain:普通视图 --> 默认只有一个分组

 

    /*

     cellcell.contentView

     //iOS7以前 --> 不区分

     //iOS7以后,官方推荐的是所有的内容都要加在cell.contentView --> 否则有可能会出现错误

    */

 

    //设置cell的选中风格

//    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

    //设置accessoryView:默认是none

    [cell setAccessoryType:UITableViewCellAccessoryDetailButton];

    //自定义accessoryView

//    [cell setAccessoryView:<#(UIView *)#>];

    //设置cell的分隔方式

    [tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLineEtched];

 //tableview.separatorInset/cell.separatorInset

    //默认cell的分割线是从15开始 --> 改成从0开始

    cell.separatorInset = UIEdgeInsetsZero;

 //分割线的颜色

    _tableView.separatorColor=[UIColor redColor];

 

 

 

多选

   

    //设置非编辑模式下 是否可以支持多选

    _tableView.allowsMultipleSelection = YES;

    //设置非编辑模式下 是否支持单选

    _tableView.allowsSelection = YES;//默认是yes 如果设置NO之后那么cell 就不能被选中了

2.两种注册UITableViewCell的方法

1⃣️在viewdidload中加载

 //首先 tableView先注册 xib  cell

    // 复用标识符

    //这里注册xib 之后 那么xib 中的cell 可以不写复用标识符

    [self.tableView registerNib:[UINib nibWithNibName:@"AppXibCell" bundle:nilforCellReuseIdentifier:@"cellID"];

 

 //注册cell

    //注册一下AppCell 类的cell 复用标识符 @"cellID" 要和下面使用的保持一致

    [self.tableView registerClass:[AppCell classforCellReuseIdentifier:@"cellID"];

2⃣️UITableViewCell

  //复用标识符

    static NSString *cellID = @"cellID";//要和xib中复用标志一样

    //使用第二种方式创建  要先注册

    AppXibCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];

 

 

 

 

/*第一种

    AppCell *cell = [tableView dequeueReusableCellWithIdentifier:str];

    if (cell == nil) {

        cell = [[[NSBundle mainBundle] loadNibNamed:@"AppCell" owner:self options:nil] lastObject];

    }

     */

    //第二种

    //注册cell

    //第一个参数:nib文件的名字

    //第二个参数:nil --> [UIBundle mainBundle]

    [tableView registerNib:[UINib nibWithNibName:@"AppCell" bundle:nilforCellReuseIdentifier:str];

    AppCell *cell = [tableView dequeueReusableCellWithIdentifier:str];

3.右侧索引标题数组ABC....XYZ

#pragma mark - 表格索引

//协议中的方法

//设置 表格视图 右侧的索引

//1. 返回 右侧索引标题数组

//这个标题的内容 是和 分区标题相对应

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {

    //判断是哪一个tableView

    if (tableView != _tableView) {

        //搜索的tableView 不需要有右侧标题

        return nil;

    }

    

    NSMutableArray *arr = [[NSMutableArray allocinit];

    //创建 26个索引标题

    //这些标题尽量要和分区 相对应

    //[arr addObject:@"#"];

    //下面的是显示搜索符号(那个小圆圈)

    [arr addObject:UITableViewIndexSearch];

    for (int i = 0; i < 26; i++) {

        NSString *str = [NSString stringWithFormat:@"%c",'A'+i];

        [arr addObject:str];

    }

    return [arr autorelease];

}

4.右侧索引标题 对应的分区索引(点击跳到第A~Z分区)

//设置 右侧索引标题 对应的分区索引

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {

    //cell右侧标题

    NSLog(@"title:%@",title);

    //右侧标题在右侧的索引

    NSLog(@"index:%d",index);

    

    //返回 对应的分区索引

    return index-1;

}

5.实现联动

-(void)scrollViewDidScroll:(UIScrollView *)scrollView

{

    _tableView1.contentOffset=_tableView2.contentOffset;

}

6.协议

//选中accessoryView会触发以下方法

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"按下的是第%d组,第%d行的右侧按钮",indexPath.section,indexPath.row);

}

//选中某一行

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"选中的是第%d组,第%d",indexPath.section,indexPath.row);

    //反选某一行:使用该方法后,不会再调用didDeselectRowAtIndexPath:这个方法

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

}

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"反选的是第%d组,第%d",indexPath.section,indexPath.row);

}

/cell 将要显示的时候调用

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"%d分区%dcell将要显示",indexPath.section,indexPath.row);

 

//修改删除时候的按钮字符串

- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {

    return @"删除";

}

 

   //设置cell 右侧附件

    cell.accessoryType=indexPath.row%5;//5种类型

//点击cell 右侧的附件 调用的函数

//下面两种类型才调用

//UITableViewCellAccessoryDetailDisclosureButton

//UITableViewCellAccessoryDetailButton

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"cell右侧附件按钮被点击");

}

#pragma mark === 插入或删除

 //打开系统自带的编辑按钮 (每个UIViewController都有一个)

    self.navigationItem.leftBarButtonItem = self.editButtonItem;

#pragma mark - 系统自带的编辑按钮会调用下面的方法

//上面系统自带的编辑按钮 点击的时候会调用下面的方法 我们只需要重写一下就可以了

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {

    //首先要调用父类的 父类的方法知道如果改变 编辑按钮的状态Edit/Done

    [super setEditing:editing animated:animated];

    //下面我们要通过这个编辑按钮来控制tableView的编辑

    [_tableView setEditing:editing animated:YES];

}

//编辑 增加 删除

/*

 UITableViewCellEditingStyleNone,//  //0

 UITableViewCellEditingStyleDelete,//删除//1

 UITableViewCellEditingStyleInsert 插入 //2

 */

 

//1.设置cell 的编辑类型

//当需要对指定cell 编辑的时候可以设置

//每个cell 编辑的时候都会调用

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {

    //奇数行 删除 偶数行 插入

#if 0

    if (indexPath.row % 2 == 0) {

        return UITableViewCellEditingStyleInsert;

    }else {

        return UITableViewCellEditingStyleDelete;

    }

#endif

    

    //三个类型交替出现

    return indexPath.row%3;

    //return UITableViewCellEditingStyleInsert;

}

//2.提交编辑

//点击编辑的cell时候会调用

//可以对指定的cell 的编辑类型进行处理

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"提交编辑");

    switch (editingStyle) {

        case UITableViewCellEditingStyleDelete://删除

        {

            //只要编辑cell 要保证tableView上显示的数据和数据源数组同步

            //1.先从数据源数组删除

            //删除指定的数据

            [_dataArr[indexPath.sectionremoveObjectAtIndex:indexPath.row];

            

            //2.删除之后必须 刷新 表格 tableView

#if 0

            //1.第一种刷新表格 reloadData 刷新整个tableView所有的表格

            /*

             reloadData 调用之后 会重新执行一下 下面协议的方法

             1.有多少分区的方法

             2.每个分区有多少行的方法

             3.获取/创建cell的方法

             */

 

            [tableView reloadData];//第一种刷新

#elif 0

            //NSArray *arr = @[indexPath];

            //对指定的多行进行重新 加载刷新

            //删除的时候是不能调用下面的方法的 下面的方法只能 修改cell内容进行刷新

            //[tableView reloadRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationRight];

            

            //2.删除的时候可以调用下面的刷新指定的多个分区

            //下面indexSet 有一个成员的集合

            NSIndexSet * indexSet = [NSIndexSet indexSetWithIndex:indexPath.section];

            [tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationFade];

#else

            //3.删除刷新

            NSArray *arr = @[indexPath];

            //传入 指定cell 的所在分区所在行对象

            //ios7之后下面的函数的动画没有效果

            [tableView deleteRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationFade];

            

#endif

        }

            break;

        case UITableViewCellEditingStyleInsert://增加

        {

            UserModel *addModel = [[UserModel allocinit];

            //增加数据模型对象

            addModel.headName = @"0033.jpg";

            addModel.userName = @"xiaohong";

            addModel.phoneNumber = @"12345678901";

            //获取一维数组

            NSMutableArray *arr = _dataArr[indexPath.section];

            //增加到数据原数组的指定的一维数组中

            [arr insertObject:addModel atIndex:indexPath.row];

            [addModel release];

            

            //刷新 数据 tableView

            //1.刷新整个表格

            //[tableView reloadData];

            

            //2.刷新指定分区

            //[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];

            //3.增加刷新表格

            [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

            

        }

            break;

            

        default:

            break;

    }

 

}

#pragma mark ===编辑多选删除===

- (void)creatDeleteButton {

    //创建数组

    _deleteDatasArr = [[NSMutableArray allocinit];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];

    button.frame = CGRectMake(0480-4432044);

    button.backgroundColor = [UIColor redColor];

    [button setTitle:@"删除" forState:UIControlStateNormal];

    button.tag = 1001;

    button.hidden = YES;//默认隐藏

    [button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:button];

}

- (void)btnClick:(UIButton *)button {

    //从数据源中删除指定的 多选的数据

    for (int i = 0; i < 26; i++) {

        NSMutableArray *arr = _dataArr[i];

        //根据另外一个数组中删除当前数组有的元素

        [arr removeObjectsInArray:_deleteDatasArr];

    }

    //清空保存的数组

    [_deleteDatasArr removeAllObjects];

    //刷新 整个表格

    [_tableView reloadData];

}

//选中cell的时候  要删除的数据保存一个新的数组

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    //获取要删除的model

    UserModel *deleteModel = _dataArr[indexPath.section][indexPath.row];

    //保存在要删除的数组中

    [_deleteDatasArr addObject:deleteModel];

}

//取消选中cell 的时候 要从保存删除cell的数组中删除取消的cell 数据

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {

    //获取取消删除的model

    UserModel *deleteModel = _dataArr[indexPath.section][indexPath.row];

    //从数组中删除掉

    [_deleteDatasArr removeObject:deleteModel];

}

/*

 UITableViewCellEditingStyleNone,//  //0

 UITableViewCellEditingStyleDelete,//删除//1

 UITableViewCellEditingStyleInsert 插入 //2

 */

 

//1.设置cell 的编辑类型

//当需要对指定cell 编辑的时候可以设置

//每个cell 编辑的时候都会调用

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {

    if (indexPath.section == 1) {

        //第二分区 编辑的时候不能多选

        return UITableViewCellEditingStyleNone;

    }

    //下面的操作UITableViewCellEditingStyleInsert|UITableViewCellEditingStyleDelete  编辑的时候就可以进行多选操作

    return UITableViewCellEditingStyleInsert|UITableViewCellEditingStyleDelete;

}

 

#pragma mark === 移动+编辑+删除

- (void)dataInit {

    _dataArr = [[NSMutableArray allocinit];

    //设置26个分区 每个分区 10  用户信息

    

    for (int i = 0; i < 26; i++) {

        //创建一维数组 存储每个分区的cell数据

        NSMutableArray *arr = [[NSMutableArray allocinit];

        for (int j = 0; j < 10; j++) {

            //存储 每一行cell 的数据

            //每一行cell 需要对应一个数据模型对象

            UserModel *model = [[UserModel allocinit];

            model.headName = [NSString stringWithFormat:@"%04d.jpg",arc4random()%24+33];

            model.userName = [NSString stringWithFormat:@"%c%d",'A'+i,j];

            model.phoneNumber = [NSString stringWithFormat:@"1383838%04d",10*i+j];

            //保存到一维数组中

            [arr addObject:model];

            [model release];

        }

        [_dataArr addObject:arr];

        [arr release];

    }

}

- (void)creatTableView {

    self.automaticallyAdjustsScrollViewInsets = NO;

 

    _tableView = [[UITableView allocinitWithFrame:CGRectMake(064320480-64style:UITableViewStylePlain];

    //设置数据源

    _tableView.dataSource = self;

    //设置代理

    _tableView.delegate = self;

    

    //打开系统自带的编辑按钮 (每个UIViewController都有一个)

    self.navigationItem.leftBarButtonItem = self.editButtonItem;

    [self.view addSubview:_tableView];

}

#pragma mark - 系统自带的编辑按钮会调用下面的方法

//上面系统自带的编辑按钮 点击的时候会调用下面的方法 我们只需要重写一下就可以了

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {

    //首先要调用父类的 父类的方法知道如果改变 编辑按钮的状态Edit/Done

    [super setEditing:editing animated:animated];

    //下面我们要通过这个编辑按钮来控制tableView的编辑

    [_tableView setEditing:editing animated:YES];

}

#pragma mark - 创建自定义的编辑按钮

- (void)creatCustomEdit {

    UIBarButtonItem *item = [[UIBarButtonItem allocinitWithTitle:@"编辑" style:UIBarButtonItemStylePlain target:self action:@selector(editClick:)];

    //作为 右按钮

    self.navigationItem.rightBarButtonItem = item;

    [item release];

}

- (void)editClick:(UIBarButtonItem *)item {

    if ([item.title isEqualToString:@"编辑"]) {

        item.title = @"完成";

    }else {

        item.title = @"编辑";

    }

    //控制tableView的编辑状态

    //首先 获取 当前tableView的编辑状态

    BOOL isEdit = _tableView.editing;

    //更改编辑状态

    [_tableView setEditing:!isEdit animated:YES];

}

#pragma mark - cell移动

//1.先设置 cell 是否可以移动

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {

    //1区分不能移动

    if (indexPath.section == 1) {

        return NO;

    }

    return YES;

}

//2.正在移动cell的时候调用的函数

//只要正在移动那么就会调用下面的函数

//从原始的位置正在移动到目标的位置

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {

    /*

     sourceIndexPathcell 的原始位置

     proposedDestinationIndexPath:移动cell 将要移动到的目标位置

     */

    //禁止把其他分区的cell 移动到第1分区

    //代码实现

    if (proposedDestinationIndexPath.section == 1) {

        return sourceIndexPath;//返回原来的位置

    }

 

    return proposedDestinationIndexPath;

    //返回值 是移动到哪个位置

}

//3.移动cell完成之后调用的方法

//已经完成移动了

//在这个函数进行处理数据源数组

//一旦实现下面的方法 那么在编辑模式下 cell 右侧就会出现一个移动的标志

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {

    NSLog(@"cell 移动完成");

    //只要修改cell  那么数据源必须要同步

    //获取原cell 的数据

    //要拥有绝对使用权

    UserModel *model = [_dataArr[sourceIndexPath.section][sourceIndexPath.rowretain];

    //从数据源中删除原来的cell的数据

    [_dataArr[sourceIndexPath.sectionremoveObject:model];

    //把原来的数据对象地址 重新插入到 数据源数组的 目标的位置

    [_dataArr[destinationIndexPath.section]  insertObject:model atIndex:destinationIndexPath.row];

    //model 用完之后 要释放

    [model release];// release 对应的是上面的retain

    

    //刷新表格

    [tableView reloadData];

}

#pragma mark - UITableViewDataSource协议

//设置有多少分区

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return _dataArr.count;

}

//每个分区有多少行

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [_dataArr[section] count];

}

//获取cell

//每次显示cell 之前都要调用这个方法

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    //创建 复用标识符

    static NSString *cellID = @"cellID";

    //

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];

    if (cell == nil) {//如果没有可复用的

        cell = [[[UITableViewCell allocinitWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID] autorelease];

    }

    //填充cell  把数据模型中的存储数据 填充到cell

    /*

    //获取一维数组

    NSArray *arr = _dataArr[indexPath.section];

    //获取数据模型

    UserModel *model =arr[indexPath.row];

    */

    UserModel *model = _dataArr[indexPath.section][indexPath.row];

    cell.imageView.image = [UIImage imageNamed:model.headName];

    cell.textLabel.text = model.userName;

    cell.detailTextLabel.text = model.phoneNumber;

    

    return cell;

}

//设置头标

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

    return [NSString stringWithFormat:@"%c",'A'+section];

}

 

#pragma mark - UITableViewDelegate

 

//修改删除时候的按钮字符串

- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {

    return @"删除";

}

 

//编辑 增加 删除

/*

 UITableViewCellEditingStyleNone,//  //0

 UITableViewCellEditingStyleDelete,//删除//1

 UITableViewCellEditingStyleInsert 插入 //2

 */

 

//1.设置cell 的编辑类型

//当需要对指定cell 编辑的时候可以设置

//每个cell 编辑的时候都会调用

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {

    //奇数行 删除 偶数行 插入

#if 0

    if (indexPath.row % 2 == 0) {

        return UITableViewCellEditingStyleInsert;

    }else {

        return UITableViewCellEditingStyleDelete;

    }

#endif

    

    //三个类型交替出现

    return indexPath.row%3;

    //return UITableViewCellEditingStyleInsert;

}

//2.提交编辑

//点击编辑的cell时候会调用

//可以对指定的cell 的编辑类型进行处理

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"提交编辑");

    switch (editingStyle) {

        case UITableViewCellEditingStyleDelete://删除

        {

            //只要编辑cell 要保证tableView上显示的数据和数据源数组同步

            //1.先从数据源数组删除

            //删除指定的数据

            [_dataArr[indexPath.sectionremoveObjectAtIndex:indexPath.row];

            

            //2.删除之后必须 刷新 表格 tableView

#if 0

            //1.第一种刷新表格 reloadData 刷新整个tableView所有的表格

            /*

             reloadData 调用之后 会重新执行一下 下面协议的方法

             1.有多少分区的方法

             2.每个分区有多少行的方法

             3.获取/创建cell的方法

             */

 

            [tableView reloadData];//第一种刷新

#elif 0

            //NSArray *arr = @[indexPath];

            //对指定的多行进行重新 加载刷新

            //删除的时候是不能调用下面的方法的 下面的方法只能 修改cell内容进行刷新

            //[tableView reloadRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationRight];

            

            //2.删除的时候可以调用下面的刷新指定的多个分区

            //下面indexSet 有一个成员的集合

            NSIndexSet * indexSet = [NSIndexSet indexSetWithIndex:indexPath.section];

            [tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationFade];

#else

            //3.删除刷新

            NSArray *arr = @[indexPath];

            //传入 指定cell 的所在分区所在行对象

            //ios7之后下面的函数的动画没有效果

            [tableView deleteRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationFade];

            

#endif

        }

            break;

        case UITableViewCellEditingStyleInsert://增加

        {

            UserModel *addModel = [[UserModel allocinit];

            //增加数据模型对象

            addModel.headName = @"0033.jpg";

            addModel.userName = @"xiaohong";

            addModel.phoneNumber = @"12345678901";

            //获取一维数组

            NSMutableArray *arr = _dataArr[indexPath.section];

            //增加到数据原数组的指定的一维数组中

            [arr insertObject:addModel atIndex:indexPath.row];

            [addModel release];

            

            //刷新 数据 tableView

            //1.刷新整个表格

            //[tableView reloadData];

            

            //2.刷新指定分区

            //[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];

            //3.增加刷新表格

            [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

            

        }

            break;

            

        default:

            break;

    }

 

}

#pragma mark - 表格索引

//协议中的方法

//设置 表格视图 右侧的索引

//1. 返回 右侧索引标题数组

//这个标题的内容 是和 分区标题相对应

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {

    NSMutableArray *arr = [[NSMutableArray allocinit];

    //创建 26个索引标题

    //这些标题尽量要和分区 相对应

    //[arr addObject:@"#"];

    //下面的是显示搜索符号

    [arr addObject:UITableViewIndexSearch];

    for (int i = 0; i < 26; i++) {

        NSString *str = [NSString stringWithFormat:@"%c",'A'+i];

        [arr addObject:str];

    }

    return [arr autorelease];

}

//设置 右侧索引标题 对应的分区索引

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {

    //cell右侧标题

    NSLog(@"title:%@",title);

    //右侧标题在右侧的索引

    NSLog(@"index:%d",index);

    

    //返回 对应的分区索引

    return index-1;

}

//cell 内容的向右缩进 级别

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {

    return 5;

}

 

#pragma mark - 搜索

 //搜索条

    UISearchBar *_searchBar;

    //搜索显示控制器   ->内部有一个tableView

    UISearchDisplayController *_searchD;

    //为搜索显示控制器中的tableView提供数据数据源数组

    NSMutableArray *_resultDataArr;

 

- (void)creatSearchView {

    //创建 搜索结果的数据源数组

    _resultDataArr = [[NSMutableArray allocinit];

    //创建搜索条

    _searchBar = [[UISearchBar allocinitWithFrame:CGRectMake(0032044)];

    //创建搜索显示控制器

    /*

     第一个参数和哪个搜索条关联

     第二个参数把搜索的内容 显示在哪个视图控制器上

     搜索的内容会显示在UISearchDisplayController中的tableView上,然后把tableView 显示  第二个参数指向的对象上

     */

    _searchD = [[UISearchDisplayController  allocinitWithSearchBar:_searchBar contentsController:self];

    //设置 数据源

    _searchD.searchResultsDataSource = self;

    //搜索结果代理

    _searchD.searchResultsDelegate = self;

    //在实现 协议的方法的时候要注意  区分tableView  是哪一个

    //把搜索条 作为表格视图的头视图

    _tableView.tableHeaderView = _searchBar;

}

 

#pragma mark - 表格索引

//协议中的方法

//设置 表格视图 右侧的索引

//1. 返回 右侧索引标题数组

//这个标题的内容 是和 分区标题相对应

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {

    //判断是哪一个tableView

    if (tableView != _tableView) {

        //搜索的tableView 不需要有右侧标题

        return nil;

    }

    

    NSMutableArray *arr = [[NSMutableArray allocinit];

    //创建 26个索引标题

    //这些标题尽量要和分区 相对应

    //[arr addObject:@"#"];

    //下面的是显示搜索符号

    //[arr addObject:UITableViewIndexSearch];

    for (int i = 0; i < 26; i++) {

        NSString *str = [NSString stringWithFormat:@"%c",'A'+i];

        [arr addObject:str];

    }

    return [arr autorelease];

}

//设置 右侧索引标题 对应的分区索引

 

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {

    //cell右侧标题

    NSLog(@"title:%@",title);

    //右侧标题在右侧的索引

    NSLog(@"index:%d",index);

    

    //返回 对应的分区索引

    return index-1;

}

 

 

#pragma mark - UITableViewDataSource协议

//设置有多少分区

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    

    if (tableView != _tableView) {//搜索的tableView

        return 1;//只有一个分区

    }

    return _dataArr.count;

}

//每个分区有多少行

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    if (tableView != _tableView) {

        //搜索的tableView

        /*

         只要点击搜索条输入每个字符都会调用 当前的协议方法

         */

        //先清空

        [_resultDataArr removeAllObjects];

        

        

        //遍历_dataArr数据源数组中 所有的数据 查找 搜索条中输入的字符

        for (NSMutableArray *arr in _dataArr) {

            //遍历一维数组 中存放的model

            for (UserModel *model in arr) {

                //查找 model 的标题名字中是否含有_searchBar.text输入的内容

                NSRange range = [model.userName rangeOfString:_searchBar.text];

                if (range.location != NSNotFound) {//找到了

                    //加到数据源数组中

                    [_resultDataArr addObject:model];

                }

            }

        }

        //返回搜索结果数据源中的个数

        return _resultDataArr.count;

    }

    //下面的是 _tableView的每个分区的行数

    

    return [_dataArr[section] count];

}

//获取cell

//每次显示cell 之前都要调用这个方法

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    

    if (tableView != _tableView) {

        //搜索的tableView

        //如果 两个tableView 用得cell 不是同一类 那么 重新设计不同类型的cell

        //创建另外一个复用标识符

        static NSString *cellName = @"cellName";

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellName];

        if (cell == nil) {

            /*

             UITableViewCellStyleDefault这一类的cell 没有副标题

             */

            cell = [[[UITableViewCell allocinitWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellName] autorelease];

        }

        UserModel *model = _resultDataArr[indexPath.row];

        //填充cell

        cell.textLabel.text = model.userName;

        cell.imageView.image = [UIImage imageNamed:model.headName];

        return cell;

        //如果 cell 的风格一样的话 没有必要设计新类型的cell

        //实际上这道题不需要创建不同风格的cell

    }

    

    //下面的是_tableViewcell

    

    //创建 复用标识符

    static NSString *cellID = @"cellID";

    //

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];

    if (cell == nil) {//如果没有可复用的

        cell = [[[UITableViewCell allocinitWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID] autorelease];

    }

    //填充cell  把数据模型中的存储数据 填充到cell

    /*

    //获取一维数组

    NSArray *arr = _dataArr[indexPath.section];

    //获取数据模型

    UserModel *model =arr[indexPath.row];

    */

    UserModel *model = _dataArr[indexPath.section][indexPath.row];

    cell.imageView.image = [UIImage imageNamed:model.headName];

    cell.textLabel.text = model.userName;

    cell.detailTextLabel.text = model.phoneNumber;

    

    return cell;

}

//设置头标

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

    if (tableView!= _tableView) {

        //搜索的tableView的头标

        return @"搜索结果";

    }

    return [NSString stringWithFormat:@"%c",'A'+section];

}

#pragma mark - QQ分组(次)

//表示当前的分区的状态

#define Section_Close 0 //收起

#define Section_Open  1 //展开

 

 

//记录26个分区的 展开状态

    NSMutableArray *_sectionStatusArr;

 

 

   

    //设置 记录每个分区的状态

    _sectionStatusArr = [[NSMutableArray allocinit];

    for (int i = 0; i < 26; i ++) {

        //转化为数字对象 存在数组中

        //初始的都是关闭分区

        [_sectionStatusArr addObject:@(Section_Close)];

    }

 

 

#pragma  mark - QQ 分组

#pragma mark - 创建头标视图

 

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    UIView *view = [[UIView allocinitWithFrame:CGRectMake(0032050)];

    view.backgroundColor = [UIColor grayColor];

    //再创建一个按钮粘在 view

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];

    button.frame = CGRectMake(0032040);

    button.backgroundColor = [UIColor blackColor];

    [button setTitle:[NSString stringWithFormat:@"%c",'A'+section] forState:UIControlStateNormal];

    button.tag = 101+section;

    [button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];

    [view addSubview:button];

    return [view autorelease];

}

- (void)btnClick:(UIButton *)button {

    //计算出分区号

    NSInteger section = button.tag - 101;

    //获取当前的状态

    BOOL isOpen = [_sectionStatusArr[section] boolValue];

    /*

    if (isOpen) {//1 展开

        //修改数组元素

        [_sectionStatusArr replaceObjectAtIndex:section withObject:@(Section_Close)];//修改为关闭

    }else {

        [_sectionStatusArr replaceObjectAtIndex:section withObject:@(Section_Open)];//修改为展开

    }*/

    [_sectionStatusArr replaceObjectAtIndex:section withObject:@(!isOpen)];

    //刷新 当前分区

    [_tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];

    //上面刷新的时候会调用 1.设置指定的分区有多少行2.获取cell

}

//头标高度

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

    return 50;

}

#pragma mark - QQ分组(较好+系统拼音)

- (void)dataInit {

    

    //我们要从沙盒中获取真实的数据 解析之后放入 数据源数组中

    NSString *path = [[NSBundle mainBundlepathForResource:@"1410new" ofType:@"plist"];

    // 得到plist 文件中的数据放入一个数组

    NSArray *plistArr = [[NSArray allocinitWithContentsOfFile:path];

    _dataArr = [[NSMutableArray allocinit];

    //解析数组 把数据放入 数据源数组中

    

    //设置26个分区 每个分区 是一个可变的一维数组

    for (int i = 0; i < 26; i++) {

        //先创建26个空数组

        //创建一维数组 存储每个分区的cell数据

        NSMutableArray *arr = [[NSMutableArray allocinit];

        [_dataArr addObject:arr];

        [arr release];

    }

    //解析 plist 文件获取的数组plistArr 把数据放入 数据模型中然后放入相应数据源中

    for (NSDictionary *dict in plistArr) {

        UserModel *model = [[UserModel allocinit];

        model.userName = dict[@"userName"];

        model.phoneNumber = dict[@"phoneNumber"];

        model.sexString = dict[@"sex"];

        model.headName = [NSString stringWithFormat:@"%04d.jpg",arc4random()%24+33];

        // model 放入 数据源数组中的指定的分区内

        //先转化为一个可变的字符串

 

系统的   

 

 NSMutableString *mutableStr = [[NSMutableString allocinitWithString:model.userName];

        //可以通过底层的函数 把汉字转化为拼音

        /*

         第一个参数:就是一个可变的字符串地址 需要强制转换

           2     转化的汉字范围  0/NULL 转化字符串中所有的汉字 (也可以指定范围) CFRange

           3   kCFStringTransformMandarinLatin 转化的拼音带声调

               kCFStringTransformStripDiacritics 不带声调

           4  是否逆序

         */

        

        //下面的函数 就是把汉字 转化为 带声调的拼音

        CFStringTransform((__bridge CFMutableStringRef) mutableStr, NULLkCFStringTransformMandarinLatinNO);

        //NSLog(@"mutable:%@",mutableStr);

        //把上面 带声调的拼接 转化为不带声调的

        CFStringTransform((__bridge CFMutableStringRef) mutableStr, NULLkCFStringTransformStripDiacriticsNO);

        //NSLog(@"mutable:%@",mutableStr);

        //获取拼音的第0个字符

        unichar c = [mutableStr characterAtIndex:0];

        [mutableStr release];

        

 

第三方

 

//获取第一个汉字字符

        unichar name = [model.userName characterAtIndex:0];

        //通过第三库 获取 汉字拼音的第一个字符

        char c = pinyinFirstLetter(name);

 

        //求出这个字符所在分区

        NSInteger section = c-'a';

        

        //model 放入section指定的分区一维数组中

        [_dataArr[section] addObject:model];

        [model release];

    }

    [plistArr release];

    

    //设置 记录每个分区的状态

    _sectionStatusArr = [[NSMutableArray allocinit];

    for (int i = 0; i < 26; i ++) {

        //转化为数字对象 存在数组中

        //初始的都是关闭分区

        [_sectionStatusArr addObject:@(Section_Close)];

    }

    

}

#pragma  mark - QQ 分组

#pragma mark - 创建头标视图

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    UIView *view = [[UIView allocinitWithFrame:CGRectMake(0032050)];

    view.backgroundColor = [UIColor grayColor];

    //再创建一个按钮粘在 view

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];

    button.frame = CGRectMake(0032040);

    button.backgroundColor = [UIColor blackColor];

    [button setTitle:[NSString stringWithFormat:@"%c",'A'+section] forState:UIControlStateNormal];

    button.tag = 101+section;

    [button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];

    [view addSubview:button];

    

    return [view autorelease];

}

- (void)btnClick:(UIButton *)button {

    //计算出分区号

    NSInteger section = button.tag - 101;

    //获取当前的状态

    BOOL isOpen = [_sectionStatusArr[section] boolValue];

    /*

    if (isOpen) {//1 展开

        //修改数组元素

        [_sectionStatusArr replaceObjectAtIndex:section withObject:@(Section_Close)];//修改为关闭

    }else {

        [_sectionStatusArr replaceObjectAtIndex:section withObject:@(Section_Open)];//修改为展开

    }*/

    [_sectionStatusArr replaceObjectAtIndex:section withObject:@(!isOpen)];

    //刷新 当前分区

    [_tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];

    //上面刷新的时候会调用 1.设置指定的分区有多少行2.获取cell

}

 

//头标高度

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

    //如果 分区没有内容 头高为0

    if ([_dataArr[section] count]==0) {

        return 0;

    }

    return 50;

}

0 0