1. 程式人生 > >iOS仿QQ分組效果

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。

原始碼