iOS仿QQ分组效果

本篇主要讲解仿QQ分组效果的实现,通过本遍的学习,估计都可以自己去实现了(老司机可以),在这里只说仿QQ分组的效果,代码简单,逻辑清晰。其他的功能的可以自行添加,好了,进入主题吧。

效果图 

下面的是其效果图

实现原理

1.创建一个表格tableView和对数据的初始化

在这里要说一下,对数据的初始化,因为要实现分组的效果,所以就多加一些数据,可能有人会问笔者,for循环的为什么是26和10,这里笔者要解释一下,26是为了A-Z一一对应的,为了做表格右边的点击。至于10,这个就是每个分区的item的个数。
  
#pragma mark - 创建表格
- (void)creatTableView {
    self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 20, kScreenSize.width, kScreenSize.height-20) style:UITableViewStylePlain];
    //设置代理和数据源
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.view addSubview:self.tableView];
}
#pragma mark - 数据
- (void)dataInit {
    _dataArr = [[NSMutableArray alloc] init];
    for (NSInteger i = 0; i < 26; i++) {
        //一维数组
        NSMutableArray *arr = [[NSMutableArray alloc] init];
        for (NSInteger j = 0; j < 10 ; j++) {
            //每个内容都有model填充
            WSModel *model = [[WSModel alloc] init];
            model.name = [NSString stringWithFormat:@"%C%@",(unichar)('A'+i),@"吴松"];
            model.QQNumber = @"qq: 3145419760";
            model.sex = @"男";
            //把模型对象放入数组中
            [arr addObject:model];
        }
        //把一维数组放入数据源
        [_dataArr addObject:arr];
    }
}
这里是用C语言的话说,是二维数组。这样的好处是减少代码量,如果你的需求的中对数据有别的要求,您可以定义两个数组:sectionArr(分区),cellArr(分区cell的个数)

2.还有一个比较重要的环节

就是为了要对每个分区的是否展开进行一定的标记,所以笔者就这样做了:
@interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
{
    //数据源数组
    NSMutableArray *_dataArr;
    //记录每个分区 的展开状态 0表示关闭 1表示展开状态
    int _sectionStatus[26];//默认:关闭
}
_sectionStatus[26],因为是26个分区,所以就数组里的元素的就是26个,默认的话,都是0,所以初始状态都是关闭状态

3.分区索引的实现

代码如下:
因为是26个分区,所以for循环的次数是26
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    if (self.tableView != tableView) {
        return nil;
    }
    
    NSMutableArray * titleArr = [[NSMutableArray alloc] init];
    for (NSInteger i = 0; i < 26; i++) {
        //设置26个分区的索引
        [titleArr addObject:[NSString stringWithFormat:@"%C",(unichar)('A'+i)]];
    }
    [titleArr addObject:@"#"];
    //返回一个数组
    return titleArr;
}
实现用户点击时,让其tableView的分区滚动到指定的分区位置
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
    //选中右侧索引之后 返回 指定分区的索引值
    return index;
}

4.分区头视图添加点击事件(重点,关键部分)

显示分区内容,代码如下:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if (self.tableView != tableView) {
        return nil;
    }
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenSize.width, 40)];
    view.backgroundColor = [UIColor lightGrayColor];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(0, 0, view.bounds.size.width, 30);
    button.tag = 101+section;
    button.backgroundColor = [UIColor yellowColor];
    if (_sectionStatus[section] != 0) {
        [button setTitle:[NSString stringWithFormat:@"%C_%@",(unichar)('A'+section),@"展开中"] forState:UIControlStateNormal];
    }else{
        [button setTitle:[NSString stringWithFormat:@"%C_%@",(unichar)('A'+section),@"关闭中"] forState:UIControlStateNormal];
    }
    [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    [view addSubview:button];
    
    return view;
}
这里没有做相应分装,只是提供思路给大家

下面是点击分区头视图的相应和实现
- (void)btnClick:(UIButton *)button {
    NSInteger section = button.tag - 101;
    //跟原来状态 取反
    _sectionStatus[section] = !_sectionStatus[section];
    //只刷新指定分区
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
}

_sectionStatus[section] = !_sectionStatus[section];
上面是取反的,同时下面的是刷新指定的分区,记得不要去刷新整个表格,这样做的话,会很耗费其性能

大家看到这里估计都明白了吧,是不是很简单呢?

小结

最后笔者要说一下,在做次功能的时候,遇到了一个坑,因为笔者的公司要求,项目里所有的本地图片都是SVG的,很耗性能,所以在笔者点击展开分区时,就会项目闪退,因为就是因为频繁加载SVG图片。最后笔者把加载SVG的代码放到了awakeFromNib方法中,当然了,有时候也是解决不了耗性能问题,建议还是使用PNG。

源代码

本篇文章对应的源代码下载地址: https://github.com/WSmalan/-QQ-
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值