#iOS分级展开

按数据进行展开,最多二级(三级目录)。

自适应展开的情况,可能是一层目录(不展开)二级目录(展开一级)三级目录展开两级

写作原因:
1.最近做的一个需求,感觉不错。
2.git上没发现,大多数是一级展开,像qq那样,没发现二级展开的代码

可以得到的东西:自适应展开,二级目录的一级展开,三级目录的二级展开

思路:最难的无非是三级的情况,此时我们第一级用tableView的headerView自定义作为第一级,点击展开的tableView作为第二级数据显示,点击tableview的每一行,我们在cell里面用tableview作为他的第三级进行显示。 其它的如果是二级的话,tableview的headerView作为第一级,点击展开的tableview作为第二级。 如果是一级的情况,只需要把tableview的header作为第二级。

1.首先建立tableView,不在赘述,但tableview得类型要用UITableViewStyleGrouped

2.第二处理数据源,将其处理成模型,放在数组中,不在赘述

3.tableView的代理

#promark -- UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    
    return _endArray.count;
    
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    ParentModel *pmodel = _endArray[section];
    if (pmodel.unfold) {
        return pmodel.children.count;
    }
    return 0;
    
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    ParentModel *pmodel = _endArray[indexPath.section];
    ParentModel *cmodel = pmodel.children[indexPath.row];
    if ([cmodel.type isEqualToString:@"unit"]) {
        TEFoldTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:foldCellIdentifier];
        if (!cell) {
            cell = [[[NSBundle mainBundle]loadNibNamed:foldCellIdentifier owner:self options:nil]lastObject];
        }
        if (indexPath.row == 0 && cmodel.unfold) {
            cell.lineView.backgroundColor = [UIColor colorFromHexRGB:@"0xdddddd"];
        }
        [cell cellConfigureCellFromModel:cmodel];
        cell.delegate = self;
        return cell;
    }
    CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:customTableViewCellIdentifier];
    if (!cell) {
        cell = [[[NSBundle mainBundle]loadNibNamed:customTableViewCellIdentifier owner:self options:nil]lastObject];
    }
    
    [cell cellConfigureContentFromModel:cmodel];
    return cell;
    
}


#pragma mark -- UITableViewDelegate

-(CGFloat)tableView:(UITableView*)tableView heightForFooterInSection:(NSInteger)section
{
    
    return 0.01f;
    
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ParentModel *testModel = _endArray[indexPath.section];
    ParentModel *childModel = testModel.children[indexPath.row];
    if (childModel.unfold && [childModel.type isEqualToString:@"unit"]) {
        return childModel.children.count * 62 + 45;
    }
    if ([childModel.type isEqualToString:@"lesson"]) {
        return 62;
    }
    return 45;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    ParentModel *testModel = _endArray[indexPath.section];
    ParentModel *childModel = testModel.children[indexPath.row];
    childModel.unfold = !childModel.unfold;
    
    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
//    [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
    [tableView deselectRowAtIndexPath:indexPath animated:true];
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    
    ParentModel *pmodel = _endArray[section];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    
    button.tag = section + 1;
    [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(buttonPress:) forControlEvents:UIControlEventTouchUpInside];
    
    
    if ([pmodel.type isEqualToString:@"lesson"]) {
        button.frame = CGRectMake(0, 0, self.view.frame.size.width, 62);
        
        UIImageView *leftImageView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 17, 17)];
        UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(CGRectGetMaxX(leftImageView.frame) + 10, 10, CGRectGetWidth(self.view.frame) - CGRectGetMaxX(leftImageView.frame) - 10, 20)];
        titleLabel.font = [UIFont systemFontOfSize:14];
        titleLabel.textAlignment = NSTextAlignmentLeft;
        titleLabel.textColor = [UIColor colorFromHexRGB:@"0x666666"];
        titleLabel.text = pmodel.name;
        
        [button addSubview:titleLabel];
        
        UILabel *subTitleLable = [[UILabel alloc]initWithFrame:CGRectMake(CGRectGetMinX(titleLabel.frame) + 5, CGRectGetMaxY(titleLabel.frame) + 5, self.view.frame.size.width/4, 15)];
        subTitleLable.font = [UIFont systemFontOfSize:11];
        subTitleLable.textColor = [UIColor colorFromHexRGB:@"0x999999"];
        subTitleLable.text = pmodel.type;
        [button addSubview:subTitleLable];
        
        UILabel *liveStatusLabel = [[UILabel alloc]initWithFrame:CGRectMake(CGRectGetMaxX(subTitleLable.frame) + 8, CGRectGetMinY(subTitleLable.frame), 35, 15)];
        liveStatusLabel.layer.cornerRadius = 7;
        liveStatusLabel.layer.masksToBounds = YES;
        liveStatusLabel.backgroundColor = [UIColor colorFromHexRGB:@"0xe93131"];
        liveStatusLabel.textColor = [UIColor colorFromHexRGB:@"0xfffefe"];
        liveStatusLabel.text = @"直播中";//通过判断时间来判断是否直播中,或已结束
        liveStatusLabel.font = [UIFont systemFontOfSize:11];
        [button addSubview:liveStatusLabel];
        liveStatusLabel.hidden = YES;
        
        switch ([pmodel.lesson_type integerValue]) {
            case 1:
                leftImageView.image = [UIImage imageNamed:@"play-round"];
                subTitleLable.text = [NSString stringWithFormat:@"%@分钟",pmodel.media_length];
                break;
            case 2:
            case 4:
#warning 这里为直播,显示直播时间,还要判断是否在直播中,无数据,有数据需要完善。
                
                leftImageView.image = [UIImage imageNamed:@"zb"];
                NSLog(@"等待处理时间戳转换");
                break;
            case 3:
            case 8:
                leftImageView.image = [UIImage imageNamed:@"cl"];
                subTitleLable.text = @"试卷";
                break;
            case 5:
            case 6:
            case 7:
                leftImageView.image = [UIImage imageNamed:@"tkd"];
                subTitleLable.text = @"材料";
                break;
                
            default:
                break;
        }
        [button addSubview:leftImageView];
        
    } else {
        button.frame = CGRectMake(0, 0, self.view.frame.size.width, 45);
        
        UILabel *tlabel = [[UILabel alloc]initWithFrame:CGRectMake(10, (44-20)/2, 200, 20)];
        [tlabel setBackgroundColor:[UIColor clearColor]];
        [tlabel setFont:[UIFont systemFontOfSize:16]];
        tlabel.textColor = [UIColor colorFromHexRGB:@"0x333333"];
        [tlabel setText:[pmodel.name stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
        [button addSubview:tlabel];
        
        UIImageView *rightImageVIew = [[UIImageView alloc]initWithFrame:CGRectMake(self.view.frame.size.width - 21,button.frame.size.height / 2 -5 , 11, 11)];
        if ([pmodel.type isEqualToString:@"unit"]) {
            rightImageVIew.frame = CGRectMake(self.view.frame.size.width - 21,button.frame.size.height / 2 -5 , 11, 7);
            if (pmodel.unfold) {
                rightImageVIew.image = [UIImage imageNamed:@"slgx"];
                
            } else {
                rightImageVIew.image = [UIImage imageNamed:@"slgx1"];
                
            }
        }else {
            if (pmodel.unfold) {
                rightImageVIew.image = [UIImage imageNamed:@"xcjq"];
            } else {
                rightImageVIew.image = [UIImage imageNamed:@"xcjq1"];
                
            }
        }
        [button addSubview:rightImageVIew];
    }
    
    UIView *lineView = [[UIView alloc]initWithFrame:CGRectMake(0, CGRectGetHeight(button.frame) - 3, self.view.frame.size.width, 3)];
    if (pmodel.unfold) {
        lineView.frame = CGRectMake(0, CGRectGetHeight(button.frame) - 1, self.view.frame.size.width, 1);
    } else {
        lineView.frame = CGRectMake(0, CGRectGetHeight(button.frame) - 3, self.view.frame.size.width, 3);
    }
    lineView.backgroundColor = [UIColor colorFromHexRGB:@"0xdddddd"];
    
    [button addSubview:lineView];
    
    return  button;
}


- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    ParentModel *model = _endArray[section];
    if ([model.type isEqualToString:@"lesson"]) {
        return 62;
    }
    return 44;
    
}

#headerView的点击方法
- (void)buttonPress:(UIButton *)sender//headButton点击
{
    ParentModel *model = _endArray[sender.tag - 1];
    //判断状态值
    if (![model.type isEqualToString:@"lesson"]) {
        model.unfold = !model.unfold;
        
    }
    [_listTableView reloadSections:[NSIndexSet indexSetWithIndex:sender.tag-1] withRowAnimation:UITableViewRowAnimationAutomatic];
    
}

model的属性

/**自己独一无二的id 不要与包id混乱*/
@property (nonatomic, copy) NSString *courseId;
/**标题*/
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *number;
/**类型 章节*/
@property (nonatomic, copy) NSString *type;
/**课件类型*/
@property (nonatomic, copy) NSString *lesson_type;
@property (nonatomic, copy) NSMutableArray *children;
/**是否打开*/
@property (nonatomic, assign) BOOL unfold;

/**如果是视频视频长度,否则返回直播开始时间*/
@property (nonatomic, copy) NSString *media_length;
/**webView链接*/
@property (nonatomic, copy) NSString *test_paper_link;

TEFoldTableViewCell的实现

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _childArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *ID = @"CustomTableViewCell";
    CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (!cell) {
        cell = [[[NSBundle mainBundle]loadNibNamed:ID owner:self options:nil]lastObject];;
    }
    ParentModel * model = _childArray[indexPath.row];
    [cell cellConfigureContentFromModel:model];
    cell.titleNameLabel.text = [model.name stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 62;
    
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ParentModel *model = _childArray[indexPath.row];
    if ([self.delegate respondsToSelector:@selector(TableViewCellDidSelectWithLessonModel:)]) {
        [self.delegate TableViewCellDidSelectWithLessonModel:model];
    }
    [tableView deselectRowAtIndexPath:indexPath animated:true];
    
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

//更换图片
-(void)setArrowImageIfUnfold:(BOOL)unfold {
    
    if (unfold) {
        [self.imageButton setImage:[UIImage imageNamed:@"slgx"] forState:UIControlStateNormal];
        
    } else {
        [self.imageButton setImage:[UIImage imageNamed:@"slgx1"] forState:UIControlStateNormal];

    }

}

- (void)cellConfigureCellFromModel:(ParentModel *)model {
    
    self.nameLabel.text = model.name;
    self.childArray = model.children;
    [self setArrowImageIfUnfold:model.unfold];

}

最底层的CustomTableVIewCell的xib不在讲述

最新代码已经上传到git

如果你觉得有用就加个star吧

演示效果
image
image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容