uitableview完整步骤
1.创建模型 布尔类型设置她的get方法是IS开头 在数据后面加上2个方法可以快速返回封装好的模型、
@interface MJFriend : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *intro;
@property (nonatomic, assign, getter = isVip) BOOL vip;
+ (instancetype)friendWithDict:(NSDictionary *)dict;
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)friendWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
1.1模型 套模型
@property (nonatomic, copy) NSString *name;
/**
* 数组中装的都是MJFriend模型
*/
@property (nonatomic, strong) NSArray *friends;
@property (nonatomic, assign) int online;
/**
* 标识这组是否需要展开, YES : 展开 , NO : 关闭
*/
@property (nonatomic, assign, getter = isOpened) BOOL opened;
+ (instancetype)groupWithDict:(NSDictionary *)dict;
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)groupWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
// 1.注入所有属性
[self setValuesForKeysWithDictionary:dict];
// 2.特殊处理friends属性
NSMutableArray *friendArray = [NSMutableArray array];
for (NSDictionary *dict in self.friends) {
MJFriend *friend = [MJFriend friendWithDict:dict];
[friendArray addObject:friend];
}
self.friends = friendArray;
}
return self;
}
然后将已经转好的模型数据放到tableviewcontroller中
- (NSArray *)groups
{
if (_groups == nil) {
NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"friends.plist" ofType:nil]];
NSMutableArray *groupArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray) {
MJFriendGroup *group = [MJFriendGroup groupWithDict:dict];
[groupArray addObject:group];
}
_groups = groupArray;
}
return _groups;
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
#pragma mark - 数据源方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.groups.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
MJFriendGroup *group = self.groups[section];
return group.friends.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.创建cell
static NSString *ID = @"friend";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
// 2.设置cell的数据
MJFriendGroup *group = self.groups[indexPath.section];
MJFriend *friend = group.friends[indexPath.row];
cell.imageView.image = [UIImage imageNamed:friend.icon];
cell.textLabel.text = friend.name;
cell.detailTextLabel.text = friend.intro;
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
MJFriendGroup *group = self.groups[section];
return group.name;
}
这样就可以在tableview中显示数据了
接着要做到的是列表的下拉与返回 下拉与不下拉 操作其实是让里面row的行数等于plist行数或者0;
创建一个headerView 创建一个类方法快速返回一个headerview
+ (instancetype)headerViewWithTableView:(UITableView *)tableView;
+ (instancetype)headerViewWithTableView:(UITableView *)tableView
{
static NSString *ID = @"header";
MJHeaderView *header = [tableView dequeueReusableHeaderFooterViewWithIdentifier:ID];
if (header == nil) {
header = [[MJHeaderView alloc] initWithReuseIdentifier:ID];
}
return header;
}
然后重写initWithReuseIdentifier方法初始化里面的子控件 把一次性的东西全部在这里初始化 但是不要设置数据 原因是重写init还在init的过程中 里面默认控制器的数据都是0
- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
// 添加子控件
// 1.添加按钮
UIButton *nameView = [UIButton buttonWithType:UIButtonTypeCustom];
nameView.backgroundColor = [UIColor redColor];
[self.contentView addSubview:nameView];
self.nameView = nameView;
// 2.添加好友数
UILabel *countView = [[UILabel alloc] init];
countView.backgroundColor = [UIColor greenColor];
[self.contentView addSubview:countView];
self.countView = countView;
}
return self;
}
frame应该在layoutSubviews方法中写
#warning 一定要调用super的方法
/**
* 当一个控件的frame发生改变的时候就会调用
*
* 一般在这里布局内部的子控件(设置子控件的frame)
*/
- (void)layoutSubviews
{
#warning 一定要调用super的方法
[super layoutSubviews];
// 1.设置按钮的frame
self.nameView.frame = self.bounds;
// 2.设置好友数的frame
CGFloat countY = 0;
CGFloat countH = self.frame.size.height;
CGFloat countW = 150;
CGFloat countX = self.frame.size.width - 10 - countW;
self.countView.frame = CGRectMake(countX, countY, countW, countH);
}
然后在控制器中添加headerview
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
// 1.创建头部控件
MJHeaderView *header = [MJHeaderView headerViewWithTableView:tableView];
// 2.给header设置数据(给header传递模型)
return header;
}
当你点击控制器告诉headerView 我的按钮被人点了
控制器想监听点击 然后 刷新表格 所以这里应该用代理方法监听点击
@protocol MJHeaderViewDelegate <NSObject>
@optional
- (void)headerViewDidClickedNameView:(MJHeaderView *)headerView;
@end
@property (nonatomic, weak) id<MJHeaderViewDelegate> delegate;
在按钮的地方添加时间 addtarget
[nameView addTarget:self action:@selector(nameViewClick) forControlEvents:UIControlEventTouchUpInside];
当好友列表被点击时
/**
* 监听组名按钮的点击
*/
- (void)nameViewClick
{
// 1.修改组模型的标记(状态取反)
self.group.opened = !self.group.isOpened;
// 2.刷新表格
if ([self.delegate respondsToSelector:@selector(headerViewDidClickedNameView:)]) {
[self.delegate headerViewDidClickedNameView:self];
}
}
把打开按钮的值取反
并使箭头朝下
/**
* 当一个控件被添加到父控件中就会调用
*/
- (void)didMoveToSuperview
{
if (self.group.opened) {
self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
} else {
self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);
}
}
控制器中
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
MJFriendGroup *group = self.groups[section];
return (group.isOpened ? group.friends.count : 0);
}