本篇主要讲解仿QQ分组效果的实现,通过本遍的学习,估计都可以自己去实现了(老司机可以),在这里只说仿QQ分组的效果,代码简单,逻辑清晰。其他的功能的可以自行添加,好了,进入主题吧。
#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-
新闻热点
疑难解答