首页 > 系统 > iOS > 正文

iOS仿QQ分组效果

2019-11-09 18:39:49
字体:
来源:转载
供稿:网友

本篇主要讲解仿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-
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表