就拿一本书的章、节、知识点为例实现方案思路大体如下:
将章、和节做为一级实现在UITableview里的每个section的header里边,原因是UITableView只提供了headerView的这种两级效果
在数据判断上将章、节、知识点做好区分,可以用type=1为章、type=2为节、type=3为知识点,这样在实现章、节、知识点的点击收缩时
效果及跳转不同的UIViewController时可以用type做好判断处理,同时在cell展示时可以控制好章、节、知识点UI展示,部分关键实现代码如下
一、将章和节的UIView组织的一个统一的UIView中并加到UIArray中作为章和节的UI展示在viewForHeaderInSection里边代码如下:
/**
* 创建分类视图
*/
- (void)loadModel
{
int i = 0, sectionNum=1;
//移除数据
[_recommandSections removeAllObjects];
[_sectionsAry removeAllObjects];
GroupCateView *cateView;
NSArray *sectionAry;
for (NSDictionary *section in _subjectListObject.chapterAry) {
//获取节基本数据高度50
sectionAry = [_subjectListObject.sectionDic objectForKey:[section objectForKey:@"id"]];
if (![sectionAry count]) {
continue;
}
[_sectionsAry addObject:section];
//获取章基本数据 高度85
cateView = [[GroupCateView alloc] initWithFrame:CGRectMake(0, 0, FD_SCREEN_MAIN_WIDTH, 50)];
cateView.backgroundColor = [UIColor clearColor];
[cateView hideViewWithSubjectSection];
cateView.section = 100000;
cateView.userInteractionEnabled = NO;
cateView.open = NO;
cateView.frame = CGRectMake(0, 0, FD_SCREEN_MAIN_WIDTH, 85);
cateView.type = 0;
//背景色
UIView *_bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, FD_SCREEN_MAIN_WIDTH, 85)];
_bgView.backgroundColor = [UIColor clearColor];
_bgView.userInteractionEnabled = NO;
//顶部灰色线
UIView *topBgLine = [[UIView alloc] initWithFrame:CGRectMake(0, 0, FD_SCREEN_MAIN_WIDTH, 19.5)];
topBgLine.backgroundColor = UIBGCOLOR_245;
[cateView addSubview:topBgLine];
//分割线一
UIView *topLine = [[UIView alloc] initWithFrame:CGRectMake(0, 19.5, FD_SCREEN_MAIN_WIDTH, .5)];
topLine.backgroundColor = [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1.0];
[_bgView addSubview:topLine];
//第几章
UILabel *_chapterNumLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 45, 15)];
_chapterNumLabel.backgroundColor = [UIColor clearColor];
_chapterNumLabel.font = [UIFont systemFontOfSize:14];
_chapterNumLabel.text = [NSString stringWithFormat:@"第%d章", sectionNum++];
_chapterNumLabel.textColor = [UIColor colorWithRed:58/255.0 green:135/255.0 blue:224/255.0 alpha:1.0];
[_bgView addSubview:_chapterNumLabel];
//章名称
UILabel *_chapterNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(55, 30, FD_SCREEN_MAIN_WIDTH-55-25, 15)];
_chapterNameLabel.backgroundColor = [UIColor clearColor];
_chapterNameLabel.text = [section objectForKey:@"name"];
_chapterNameLabel.textColor = [UIColor blackColor];
_chapterNameLabel.font = [UIFont systemFontOfSize:14];
[_bgView addSubview:_chapterNameLabel];
//章描述
UILabel *_chapterIntroLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 48, FD_SCREEN_MAIN_WIDTH-30, 20)];
_chapterIntroLabel.backgroundColor = [UIColor clearColor];
_chapterIntroLabel.text = [NSString stringWithFormat:@"共%@小节,%@个核心考点", [section objectForKey:@"sections"], [section objectForKey:@"points"]];
_chapterIntroLabel.font = [UIFont systemFontOfSize:13];
_chapterIntroLabel.textColor = [UIColor grayColor];
[_bgView addSubview:_chapterIntroLabel];
//中部灰色线
UIView *middleBgLine = [[UIView alloc] initWithFrame:CGRectMake(0, 84.5, FD_SCREEN_MAIN_WIDTH, .5)];
middleBgLine.backgroundColor = [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1.0];
[_bgView addSubview:middleBgLine];
cateView.backBtn.hidden = YES;
cateView.backBtn.userInteractionEnabled = NO;
cateView.cateName.hidden = YES;
[cateView addSubview:_bgView];
//底部灰色线
UIView *bottomBgLine = [[UIView alloc] initWithFrame:CGRectMake(0, 85+49.5, FD_SCREEN_MAIN_WIDTH, .5)];
bottomBgLine.backgroundColor = [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1.0];
[_bgView addSubview:bottomBgLine];
cateView.backgroundColor = [UIColor whiteColor];
[_recommandSections addObject:cateView];
for (NSDictionary *sectionDic in sectionAry) {
//获取节信息
cateView = [[GroupCateView alloc] initWithFrame:CGRectMake(0, 0, FD_SCREEN_MAIN_WIDTH, 50)];
cateView.backgroundColor = [UIColor clearColor];
[cateView hideViewWithSubjectSection];
cateView.delegate = self;
cateView.section = i;
cateView.open = NO;
//type:0章 type:1节
cateView.type = 1;
//版块箭头左右图标
UIImageView *_schoolArrayImgView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 19, 6, 12)];
_schoolArrayImgView.tag = 1000+i;
_schoolArrayImgView.image = [UIImage imageNamed:@"icon_major_array_right"];
[cateView addSubview:_schoolArrayImgView];
//版块名称
NSString *name = [NSString stringWithFormat:[sectionDic objectForKey:@"name"], i++];
cateView.cateName.textColor = [UIColor colorWithRed:(51.0/255.0f) green:(51.0/255.0f) blue:(51/255.0f) alpha:1.0f];
cateView.cateName.textAlignment = NSTextAlignmentLeft;
cateView.cateName.font = [UIFont systemFontOfSize:14];
cateView.cateName.backgroundColor = [UIColor clearColor];
cateView.cateName.contentMode = UIViewContentModeCenter;
cateView.cateName.text = name;
[cateView addSubview:cateView.cateName];
cateView.frame = CGRectMake(0, 0, FD_SCREEN_MAIN_WIDTH, 50);
cateView.flag = 0;
//分割线一
cateView.backgroundColor = [UIColor clearColor];
UIView *topLine = [[UIView alloc] initWithFrame:CGRectMake(0, 49.5, FD_SCREEN_MAIN_WIDTH, .5)];
topLine.backgroundColor = [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1.0];
[cateView addSubview:topLine];
//版块箭头左右图标
_schoolArrayImgView.frame = CGRectMake(10, 19, 6, 12);
cateView.cateName.frame = CGRectMake(23, 18, 260, 15);
cateView.backBtn.frame = CGRectMake(0, 0, FD_SCREEN_MAIN_WIDTH, 50);
cateView.backBtn.backgroundColor = [UIColor clearColor];
cateView.backgroundColor = [UIColor whiteColor];
[_recommandSections addObject:cateView];
[_sectionsAry addObject:sectionDic];
i++;
}
}
//获取总段数
_total = [_recommandSections count];
}
显示到section中的headerView视图里边
#pragma mark - tableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
GroupCateView *CateView = [_recommandSections objectAtIndex:section];
if(CateView.type == 0){
return 0;
}
//获取每个分类的CELL数据
NSDictionary *sectionDic = [_sectionsAry objectAtIndex:section];
if ([[sectionDic objectForKey:@"type"] intValue] == 1) {
return 0;
}
NSString *pid = [sectionDic objectForKey:@"id"];
return CateView.open?[[_subjectListObject.pointDic objectForKey:pid] count]:0;
}
/** cell高度 */
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}
/** 头部cell高度 */
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
float height;
GroupCateView *cateView = [_recommandSections objectAtIndex:section];
if (cateView.type == 1) { //节
height = 50;
}else{ //章
height = 85;
}
return height;
}
/**
* section底部间距
*/
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 0.01;
}
/** 部cell视图 */
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
GroupCateView *cateView = [_recommandSections objectAtIndex:section];
return cateView;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return _total;
}
heightForFooterInSection 的间距设置为0.01不设置的话用
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, FD_SCREEN_MAIN_WIDTH, FD_SCREEN_SHOW_HEIGHT)
style:UITableViewStyleGrouped];
这咱方式展示时每个行会有默认间隔达不到UI上的效果
最后实现节与知识点的展示收缩效果即可,部分代码如下
#pragma mark - GroupCateViewdelegate
- (void)selectedWith:(GroupCateView *)view{
UIImageView *_aImgView;
if(view.tag > 5000) return;
//将上一个小图标重置
if (_tmpSection>=1000) {
_aImgView = (UIImageView *)[self.view viewWithTag:(_tmpSection)];
_aImgView.frame = CGRectMake(10, 19, 6, 12);
_aImgView.image = [UIImage imageNamed:@"icon_major_array_right"];
}
//获取要更改的icon小图标
_tmpSection = view.section+1000;
_aImgView = (UIImageView *)[view viewWithTag:(1000+view.section)];
if (view.open) {
//控制icon图标方向
_aImgView.frame = CGRectMake(10, 19, 6, 12);
_aImgView.image = [UIImage imageNamed:@"icon_major_array_right"];
for(int i = 0;i<[_recommandSections count];i++){
GroupCateView *head = [_recommandSections objectAtIndex:i];
head.open = NO;
[head.backBtn setBackgroundImage:[UIImage imageNamed:@"btn_momal"] forState:UIControlStateNormal];
}
[_tableView reloadData];
return;
}else{
//控制icon图标方向
_aImgView.frame = CGRectMake(7, 23, 12, 6);
_aImgView.image = [UIImage imageNamed:@"icon_major_array_down"];
}
_currentSection = view.section;
[self reset];
}
/** 界面重置 */
- (void)reset
{
for(int i = 0;i<[_recommandSections count];i++){
GroupCateView *head = [_recommandSections objectAtIndex:i];
if(head.section == _currentSection){
head.open = YES;
[head.backBtn setBackgroundImage:[UIImage imageNamed:@"btn_nomal"] forState:UIControlStateNormal];
}else {
[head.backBtn setBackgroundImage:[UIImage imageNamed:@"btn_momal"] forState:UIControlStateNormal];
head.open = NO;
}
}
[_tableView reloadData];
}
其中- (void)selectedWith:(GroupCateView *)view为GroupCateView代理这样点击每个节时就达了预期的效果:
实现效果如图: