网上的二级列表,QQ分组的demo比比皆是,但是适合自己的才是最好了,我自己写了个适合自己用的,记录一下吧。以后用到的话就直接commond + v了
先上gif图
gif.gif- 首先是数据
NSArray *data = @[@{
@"title":@"世上事仿佛都经不起后来的推敲",
@"cellData":@[@{
@"content":@"诸如,后来你变了"
},
@{
@"content":@"后来我卷了"
}]
},
@{
@"title":@"后来故人零落",
@"cellData":@[@{
@"content":@"新人款款前来"
},
@{
@"content":@"后来时光静默"
},
@{
@"content":@"过往逆流成河"
}]
},
@{
@"title":@"模糊的青天雨落",
@"cellData":@[@{
@"content":@"遗失的年少轻彻"
},@{
@"content":@"此去的别后经年"
},
@{
@"content":@"他乡的阁楼冷彻"
}]
},
@{
@"title":@"我还倚着些微的坚强",
@"cellData":@[@{
@"content":@"却已背离曾经的方向"
},
@{
@"content":@"半盏酒后"
},
@{
@"content":@"便是遗忘"
}]
}];
- 创建model
HeaderModel.h
#import <Foundation/Foundation.h>
#import "CellModel.h"
@interface HeaderModel : NSObject
@property (nonatomic,copy) NSString *title;
@property (nonatomic,strong) NSArray *cellData;
@end
HeaderModel.m
#import "HeaderModel.h"
@implementation HeaderModel
MJCodingImplementation
+(NSDictionary *)mj_objectClassInArray
{
return @{
@"cellData":@"CellModel"
};
}
@end
CellModel.h
#import <Foundation/Foundation.h>
#import "MJExtension.h"
@interface CellModel : NSObject
@property (nonatomic,copy) NSString *content;
@end
CellModel.m
#import "CellModel.h"
@implementation CellModel
MJCodingImplementation
@end
- UIViewController
#import "ViewController.h"
#import "HeaderModel.h"
#import "Cell.h"
#import "CellModel.h"
#import "HeaderView.h"
@interface ViewController ()
<UITableViewDelegate,UITableViewDataSource,HeaderViewDelegate>
{
int _currentRow;
int _currentSection;
}
@property (nonatomic, strong)UITableView *tableView;
@property(nonatomic,strong)NSMutableArray * headViewArray;
@property (nonatomic,strong) NSMutableArray *data;
@end
@implementation ViewController
-(NSMutableArray *)data
{
if (!_data) {
_data = [NSMutableArray array];
}
return _data;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.data = [HeaderModel mj_objectArrayWithKeyValuesArray:data];
self.headViewArray = [NSMutableArray array];
int i = 0;
for (HeaderModel *model in self.data) {
HeaderView *headerView = [[HeaderView alloc]init];
headerView.headerModel = model;
headerView.delegate = self;
headerView.index = i;
i++;
[self.headViewArray addObject:headerView];
}
[self.view addSubview:self.tableView];
}
- 创建tableView
-(UITableView *)tableView
{
if (!_tableView) {
_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 10, self.view.width, self.view.height - 20) style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.estimatedRowHeight = 0;
_tableView.estimatedSectionHeaderHeight = 0;
_tableView.estimatedSectionFooterHeight = 0;
_tableView.backgroundColor = [UIColor whiteColor];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
return _tableView;
}
- UITableviewDelegate---UITableviewDataSource
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 60;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return self.headViewArray[section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
HeaderView* headView = self.headViewArray[section];
HeaderModel *headerModel = self.data[section];
return headView.open?headerModel.cellData.count:0;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [self.headViewArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Cell *cell = [Cell cellWithTableView:tableView];
HeaderModel *headerModel = self.data[indexPath.section];
CellModel *model = headerModel.cellData[indexPath.row];
cell.model = model;
return cell;
}
-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
return 50;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(@"click---%ld section and %ld row",(long)indexPath.section,(long)indexPath.row);
}
#pragma mark - HeadViewdelegate
-(void)selectedWith:(HeaderView *)view{
_currentRow = -1;
if (view.open) {
for(int i = 0;i<[self.headViewArray count];i++)
{
HeaderView *head = [self.headViewArray objectAtIndex:i];
head.open = NO;
[UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
head.backBtn.layer.transform = CATransform3DMakeRotation(0, 0, 0, 1);
} completion:NULL];
}
[_tableView reloadData];
return;
}
_currentSection = (int)view.index;
[self reset];
}
//界面重置
- (void)reset
{
for(int i = 0;i<[self.headViewArray count];i++)
{
HeaderView *head = [self.headViewArray objectAtIndex:i];
if(head.index == _currentSection)
{
head.open = YES;
[UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
head.backBtn.layer.transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
} completion:NULL];
}else {
[UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
head.backBtn.layer.transform = CATransform3DMakeRotation(0, 0, 0, 1);
} completion:NULL];
head.open = NO;
}
}
[_tableView reloadData];
}
- 创建SectionHeaderView
HeaderView.h
#import <UIKit/UIKit.h>
@class HeaderView,HeaderModel;
@protocol HeaderViewDelegate <NSObject>
-(void)selectedWith:(HeaderView *)view;
@end
@interface HeaderView : UIView
@property (nonatomic,weak) id<HeaderViewDelegate> delegate;
@property(nonatomic, assign) NSInteger index;
@property(nonatomic, assign) BOOL open;
@property(nonatomic, retain) UIButton* backBtn;
@property(nonatomic, strong) HeaderModel * headerModel;
@end
HeaderView.m
#import "HeaderView.h"
#import "UIView+Extension.h"
#import "HeaderModel.h"
@interface HeaderView()
@property (nonatomic,strong) UIView *backView;
@property (nonatomic,weak) UILabel *label;
@end
@implementation HeaderView
-(instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
_open = NO;
CGFloat titleFont = 15;
self.backgroundColor = [UIColor whiteColor];
UIView *backView = [[UIView alloc]init];
backView.backgroundColor = [UIColor whiteColor];
self.backView = backView;
[self addSubview:backView];
//时间
UILabel *label = [[UILabel alloc]init];
label.font = [UIFont systemFontOfSize:titleFont] ;
label.textColor = [UIColor blackColor];
label.textAlignment = NSTextAlignmentLeft;
[backView addSubview:label];
self.label = label;
//箭头
UIButton* btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn addTarget:self action:@selector(doSelected) forControlEvents:UIControlEventTouchUpInside];
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSelected)]];
[btn setImage:[UIImage imageNamed:@"向下箭头-4"] forState:UIControlStateNormal];
[btn.imageView setContentMode:UIViewContentModeScaleAspectFill];
[backView addSubview:btn];
self.backBtn = btn;
}
return self;
}
-(void)layoutSubviews
{
[super layoutSubviews];
//位置
self.backView.frame = CGRectMake(0, 5, self.width, self.height - 10);
self.label.frame = CGRectMake(10, (self.backView.height - 40)/2, self.backView.width - 60, 40);
self.backBtn.frame = CGRectMake(self.width - self.height +10, 0, self.height - 10, self.height - 10);
}
-(void)setHeaderModel:(HeaderModel *)headerModel
{
_headerModel = headerModel;
self.label.text = headerModel.title;
}
-(void)doSelected{
if (_delegate && [_delegate respondsToSelector:@selector(selectedWith:)]){
[_delegate selectedWith:self];
}
}
- 创建Cell
Cell.h
#import <UIKit/UIKit.h>
@class CellModel;
@interface Cell : UITableViewCell
+(instancetype)cellWithTableView:(UITableView *)tableView;
@property (nonatomic,strong) CellModel *model;
@end
Cell.m
#import "Cell.h"
#import "CellModel.h"
#import "UIView+Extension.h"
@interface Cell ()
@property (nonatomic,weak) UILabel *piCiLabel;
@end
@implementation Cell
+(instancetype)cellWithTableView:(UITableView *)tableView
{
static NSString *CellID = @"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellID];
if (cell == nil) {
cell = [[Cell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellID];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// 添加自己可能显示的所有子控件
self.backgroundColor = [UIColor whiteColor];
UILabel *piCiLabel = [[UILabel alloc]init];
piCiLabel.font = [UIFont systemFontOfSize:14] ;
piCiLabel.textColor = [UIColor lightGrayColor];
piCiLabel.textAlignment = NSTextAlignmentLeft;
[self.contentView addSubview:piCiLabel];
self.piCiLabel = piCiLabel;
}
return self;
}
-(void)setModel:(CellModel *)model
{
_model = model;
self.piCiLabel.text = model.content;
}
-(void)layoutSubviews
{
[super layoutSubviews];
self.piCiLabel.frame = CGRectMake(20, (self.height - 40)/2, self.width - 25, 40);
}
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end
最近发现一个问题,就是如果列表数据多了的话,点击最下面的二级列表,tableview就会自动回滚到最上面去,一直以为是刷新了整个tableview导致的,后来发现并不是,给tableview添加这三个属性就好了
_tableView.estimatedRowHeight = 0;
_tableView.estimatedSectionHeaderHeight = 0;
_tableView.estimatedSectionFooterHeight = 0;
网友评论