IOS TableView组件五:TableView分组列表

文章目录

  • 基本tableView
    • 取消tableview默认的分割线
    • 创建一个自定义的分割线
    • 重用方式
    • 创建完plist文件后,在model文件中对应创建属性。
  • 获取plist文件:
  • cellview需要一个更新函数
  • 注册了和没注册的区别
  • 设置有多少项,和每项的头高和视图
  • GroupCell.h
  • GroupCell.m
  • 现在的效果
  • 创建GroupHeaderView和HeaderButton
  • headerButton.m
  • GroupHeaderView
    • GroupHeaderView.h
    • GroupHeaderView.m
  • MainViewController.m
  • demo

基本tableView

取消tableview默认的分割线

 [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];

创建一个自定义的分割线

UIView *lineView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), 0.35)];
        lineView.backgroundColor=[UIColor blackColor];
        [self.contentView addSubview:lineView];

重用方式

#import "MainViewController.h"
#import "GroupCell.h"
@interface MainViewController ()

@property (nonatomic,strong)UITableView *tableView;

@end

@implementation MainViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setTitle:@"QQ分组"];
    [self.view setBackgroundColor:[UIColor whiteColor]];
    
    [self setTableView:[[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain]];
    [self.tableView setDataSource:self];
    [self.tableView setDelegate:self];
    [self.tableView registerClass:[GroupCell class] forCellReuseIdentifier:@"GroupCell"];
    [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
    [self.view addSubview:self.tableView];
}

#pragma mark -Table view delegate -
#pragma mark -Table view data Source -

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    
    return 5;
}
-(UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    GroupCell *cell= [tableView dequeueReusableCellWithIdentifier:@"GroupCell"];
    if(!cell){
        
    }
    return cell ;
}


@end

效果:
IOS TableView组件五:TableView分组列表_第1张图片

创建完plist文件后,在model文件中对应创建属性。

重写:防止赋值的时候不匹配导致程序崩溃

- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
}

frends需要重写他的set函数

- (void)setFriends:(NSArray *)friends{
    NSMutableArray *tempArray=[NSMutableArray array];
    for(NSDictionary *dataDict in friends){
        FriendModel *model=[[FriendModel alloc]init];
        [model setValuesForKeysWithDictionary:dataDict];
        [tempArray addObject:model];
    }
    _friends=[tempArray copy];
}

获取plist文件:

GroupModel.m中定义类函数

+(instancetype)modelWithDict:(NSDictionary *)dict{
    GroupModel *model=[[GroupModel alloc] init];
    [model setValuesForKeysWithDictionary:dict];
    return model;
}

MainViewController.m中懒加载方式获取数据

-(NSArray *)groupArray{
    if(!_groupArray){
        NSString *path=[[NSBundle mainBundle]pathForResource:@"qq_group" ofType:@"plist"];
        NSArray *groupArrayFile=[NSArray arrayWithContentsOfFile:path];
        
        NSMutableArray *tempArray=[NSMutableArray array];
        for(NSDictionary *dic in groupArrayFile){
            GroupModel *model=[GroupModel modelWithDict:dic];
            [tempArray addObject:model];
        }
        _groupArray=[tempArray copy];
    }
    return _groupArray;
}

cellview需要一个更新函数

该函数里给子视图的图片名,文本内容赋值

-(void)updateWithFriendModel:(FriendModel *)model{
    [self.avatarImageView setImage:[UIImage imageNamed:model.icon]];
    [self.titleLabel setText:model.name];
    [self.subtitleLabel setText:model.message];
}

注册了和没注册的区别

没注册:

-(UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    GroupCell *cell= [tableView dequeueReusableCellWithIdentifier:@"GroupCell"];
    if(!cell){
         cell=[[GroupCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"GroupCell"];
    }
    GroupModel *groupModel=self.groupArray[indexPath.section];
    [cell updateWithFriendModel:groupModel.friends[indexPath.row]];
    return cell ;
}

注册:

-(UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    GroupCell *cell= [tableView dequeueReusableCellWithIdentifier:@"GroupCell"];
    GroupModel *groupModel=self.groupArray[indexPath.section];
    [cell updateWithFriendModel:groupModel.friends[indexPath.row]];
    return cell ;
}

设置有多少项,和每项的头高和视图

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    return 40;
}
//如果没有下面这个函数,上面那个函数不起作用。
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    return nil;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return self.groupArray.count;
}

GroupCell.h

#import 
#import "FriendModel.h"
NS_ASSUME_NONNULL_BEGIN

@interface GroupCell : UITableViewCell
@property (nonatomic,strong)UIImageView  *avatarImageView;
@property (nonatomic,strong)UILabel *titleLabel;
@property (nonatomic,strong)UILabel *subtitleLabel;

-(void)updateWithFriendModel:(FriendModel *)model;
@end

GroupCell.m

cell的内容用的都是groupModel.friends[indexPath.row]],friendModel

#import "GroupCell.h"

@implementation GroupCell

/*- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}*/
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    self=[super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if(self){
        [self setAvatarImageView:[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 60, 60)]];
        [self.contentView addSubview:self.avatarImageView];
        
        [self setTitleLabel:[[UILabel alloc]initWithFrame:CGRectMake(75, 7, 120, 21)]];
        [self.contentView addSubview:self.titleLabel];
        
        [self setSubtitleLabel:[[UILabel alloc]initWithFrame:CGRectMake(75, 34, 250, 21)]];
        [self.contentView addSubview:self.subtitleLabel];
        
        UIView *lineView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), 0.35)];
        lineView.backgroundColor=[UIColor blackColor];
        [self.contentView addSubview:lineView];
    }
    return self;
}
-(void)updateWithFriendModel:(FriendModel *)model{
    [self.avatarImageView setImage:[UIImage imageNamed:model.icon]];
    [self.titleLabel setText:model.name];
    [self.subtitleLabel setText:model.message];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end

现在的效果

IOS TableView组件五:TableView分组列表_第2张图片

创建GroupHeaderView和HeaderButton

GroupHeaderView继承自UITableViewHeaderFooterView
HeaderButton继承自UIButton

headerButton.m

图像按原大小居中显示(按图标的具体情况,本代码没有使用居中,因为会使图片显示异常):

[button.imageView setContentMode:UIViewContentModeCenter];

重新规划image view的矩形区域:

-(CGRect)imageRectForContentRect:(CGRect)contentRect{
    CGFloat height=CGRectGetHeight(contentRect);
    return CGRectMake(0, 0, height, height);
}
-(CGRect)titleRectForContentRect:(CGRect)contentRect{
    return CGRectMake(40, 0, CGRectGetWidth(contentRect)-55, CGRectGetHeight(contentRect));
}
#import "HeaderButton.h"

@implementation HeaderButton
+(instancetype)buttonWithTarget:(id)target action:(SEL)action{
    HeaderButton *button=[self buttonWithType:UIButtonTypeCustom];
    [button setFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), 40)];
    [button setBackgroundColor:[UIColor blackColor]];
    [button.titleLabel setFont:[UIFont systemFontOfSize:18]];
    [button.titleLabel setTextColor:[UIColor whiteColor]];
    [button.layer setBorderColor:[UIColor whiteColor].CGColor];
    [button.layer  setBorderWidth:0.5];
    [button setImage:[UIImage imageNamed:@"b.png"] forState:UIControlStateNormal];
    //[button.imageView setContentMode:UIViewContentModeCenter];//图像居中
    [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
    return button;
}
-(CGRect)imageRectForContentRect:(CGRect)contentRect{
    CGFloat height=CGRectGetHeight(contentRect);
    return CGRectMake(0, 0, height, height);
}
-(CGRect)titleRectForContentRect:(CGRect)contentRect{
    return CGRectMake(40, 0, CGRectGetWidth(contentRect)-55, CGRectGetHeight(contentRect));
 }
@end

GroupHeaderView

GroupHeaderView中去添加button,并指明和实现相应函数。
定义的方法要用initWithReuseIdentifier,完成button的创建。
按更新数据展示的update函数,按model实现button的文本,图标的转向,如果打开了isOpen为1,则翻转90度,如果为0,则保持翻转前的状态,一开始都是0.。
声明一个isOpen值只是用于在函数调用的时候给个参数,值是多少并不影响。
用block的方式给按钮的响应函数定义,具体的block内容在MainViewController.m中定义。

@property (nonatomic,assign,readonly)BOOL isOpen;

GroupHeaderView.h

#import 
#import "HeaderButton.h"
#import "GroupModel.h"
NS_ASSUME_NONNULL_BEGIN

@interface GroupHeaderView : UITableViewHeaderFooterView
@property (nonatomic,strong) HeaderButton *headerButton;
@property (nonatomic,assign,readonly)BOOL isOpen;
@property (nonatomic,copy)void (^openHandler)(BOOL isOpen);
-(void)updateHeaderViewWithModel:(GroupModel*)model;
@end

GroupHeaderView.m

#import "GroupHeaderView.h"

@implementation GroupHeaderView

-(instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier{
    self=[super initWithReuseIdentifier:reuseIdentifier];
    if(self){
        [self setHeaderButton:[HeaderButton buttonWithTarget:self action:@selector(headerButtonClicked:)]];
        [self.contentView addSubview:self.headerButton];
    }
    return self;
}
-(void)updateHeaderViewWithModel:(GroupModel *)model{
    [self.headerButton setTitle:[NSString stringWithFormat:@"%@ (%@)",model.title,model.online] forState:UIControlStateNormal];
    if(model.isOpen){
        [self.headerButton.imageView setTransform:CGAffineTransformMakeRotation(M_PI_2)];
    }
    else{
        [self.headerButton.imageView setTransform:CGAffineTransformIdentity];
    }
    _isOpen=!model.isOpen;
}
#pragma mark -Actions -
-(void)headerButtonClicked:(HeaderButton*)sender{
    self.openHandler(_isOpen);
}
@end

MainViewController.m

cell的内容用的都是groupModel.friends[indexPath.row]],friendModel。
header的内容才用到:groupMode.title,groupMode.online
注册重用的header view:

self.tableView registerClass:[GroupHeaderView class] forHeaderFooterViewReuseIdentifier:@"HeaderView"];

设置block:

 [headerView setOpenHandler:^(BOOL isOpen) {
        groupModel.isOpen=!groupModel.isOpen;
        [tableView reloadData];

是否展开,是按model.isOpen返回numberOfRowsInSection。

#import "MainViewController.h"
#import "GroupCell.h"
#import "GroupModel.h"
#import "FriendModel.h"
#import "GroupHeaderView.h"
@interface MainViewController ()

@property (nonatomic,strong)UITableView *tableView;
@property (nonatomic,strong)NSArray *groupArray;

@end

@implementation MainViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setTitle:@"QQ分组"];
    [self.view setBackgroundColor:[UIColor whiteColor]];
    
    [self setTableView:[[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain]];
    [self.tableView setDataSource:self];
    [self.tableView setDelegate:self];
    [self.tableView registerClass:[GroupCell class] forCellReuseIdentifier:@"GroupCell"];
    [self.tableView registerClass:[GroupHeaderView class] forHeaderFooterViewReuseIdentifier:@"HeaderView"];
    [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
    [self.view addSubview:self.tableView];
}
-(NSArray *)groupArray{
    if(!_groupArray){
        NSString *path=[[NSBundle mainBundle]pathForResource:@"qq_group" ofType:@"plist"];
        NSArray *groupArrayFile=[NSArray arrayWithContentsOfFile:path];
        
        NSMutableArray *tempArray=[NSMutableArray array];
        for(NSDictionary *dic in groupArrayFile){
            GroupModel *model=[GroupModel modelWithDict:dic];
            [tempArray addObject:model];
        }
        _groupArray=[tempArray copy];
    }
    return _groupArray;
}

#pragma mark -Table view delegate -
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 60;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    return 40;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    GroupHeaderView *headerView=[tableView dequeueReusableHeaderFooterViewWithIdentifier:@"HeaderView"];
    GroupModel *groupModel=self.groupArray[section];
    [headerView updateHeaderViewWithModel:groupModel];
    [headerView setOpenHandler:^(BOOL isOpen) {
        groupModel.isOpen=!groupModel.isOpen;
        [tableView reloadData];
        
    }];
    return headerView;
}
#pragma mark -Table view data Source -
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return self.groupArray.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    GroupModel *model=self.groupArray[section];
    return model.isOpen? model.friends.count:0;
}
-(UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    GroupCell *cell= [tableView dequeueReusableCellWithIdentifier:@"GroupCell"];
    GroupModel *groupModel=self.groupArray[indexPath.section];
    [cell updateWithFriendModel:groupModel.friends[indexPath.row]];
    return cell ;
}


@end

demo

demo

你可能感兴趣的:(IOS,UI,TableView)