美文网首页iosiOS控件封装深入浅出iOS
代码优化-更精简的tableView,抽离tableView D

代码优化-更精简的tableView,抽离tableView D

作者: sands_yu | 来源:发表于2017-02-23 10:26 被阅读445次
title: 代码优化-更精简的tableView,抽离tableView DataSource Delegate
tags: [iOS,APP,开发]

前言

UITableView无疑是我们在开发iOS应用中使用频率非常高的一个控件,使用方法无外乎创建对象,关联delegate,datasource,实现对应方法.

几乎是在每一次使用UITableView的时候,都会去调用几个固定的方法,例如

//返回数量
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
//返回高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
//返回cell实例对象
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//cell点击事件
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

这无疑是多了很多重复性质的代码,是否有办法可以简化UITableView的使用,避免这些重复性质的代码,同时能兼容大部分情况UITableView的使用呢?

将UITableView的Deleaget,DataSource抽离出来无疑是一个比较好的办法,实现一个通用的负责代理方法实现的类,通过block来回调,减少VC代码量.

代码实例

通用处理类CustomDeleagte.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

typedef void (^TableViewCellConfigureBlock)(NSIndexPath* indexPath, id cell, id item);
typedef void (^TableViewCellDidSelectBlock)(NSIndexPath* indexPath, id cell, id item);
typedef CGFloat (^TableViewCellHeightBlock)(NSIndexPath* indexPath, id item);


@interface CustomDeleagte : NSObject <UITableViewDataSource,UITableViewDelegate>

- (id)initWithItems:(NSArray *)aItems
     cellIdentifier:(NSString *)aIdentifier
 configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock
    cellHeightBlock:(TableViewCellHeightBlock)aHeightBlock
     didSelectBlock:(TableViewCellDidSelectBlock)aDidSelectBlock;

- (void)handleTableViewDataSourceAndDelegate:(UITableView*)aTableView;

- (id)itemAtIndexPath:(NSIndexPath *)indexPath;

@property (nonatomic, copy) NSArray *items;

@end

1.TableViewCellConfigureBlock用于传入数据源,加载数据
2.TableViewCellDidSelectBlock回调点击事件
3.TableViewCellHeightBlock计算cell高度

三个block基本涵盖了UITableView的一般使用.


通用处理类实现CustomDeleagte.m

#import "CustomDeleagte.h"
#import "UITableViewCell+Extension.h"

@interface CustomDeleagte()
@property (nonatomic, copy) NSString* cellIdentigier;
@property (nonatomic, copy) TableViewCellConfigureBlock configureCellBlock;
@property (nonatomic, copy) TableViewCellDidSelectBlock didSelectBlock;
@property (nonatomic, copy) TableViewCellHeightBlock heightBlock;
@end

@implementation CustomDeleagte

- (id)initWithItems:(NSArray *)aItems
     cellIdentifier:(NSString *)aIdentifier
 configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock
    cellHeightBlock:(TableViewCellHeightBlock)aHeightBlock
didSelectBlock:(TableViewCellDidSelectBlock)aDidSelectBlock{
    self = [super init];
    if (self) {
        self.items = aItems;
        self.cellIdentigier = aIdentifier;
        self.configureCellBlock = aConfigureCellBlock;
        self.heightBlock = aHeightBlock;
        self.didSelectBlock = aDidSelectBlock;
    }
    return self;
}


- (id)itemAtIndexPath:(NSIndexPath*)indexPath{
    return self.items[(NSUInteger)indexPath.row];
}

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

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentigier];
    if (!cell) {
        [UITableViewCell registerTabelView:tableView nibIdentifier:self.cellIdentigier];
        cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentigier];
    }
    id item = [self itemAtIndexPath:indexPath];
    self.configureCellBlock(indexPath,cell,item);
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    id item = [self itemAtIndexPath:indexPath];
    id cell = [tableView cellForRowAtIndexPath:indexPath];
    self.didSelectBlock(indexPath,cell,item);
}

//注册delegate,datasource
- (void)handleTableViewDataSourceAndDelegate:(UITableView *)aTableView{
    aTableView.delegate = self;
    aTableView.dataSource = self;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    id item = [self itemAtIndexPath:indexPath];
    return self.heightBlock(indexPath,item);
}
@end

给UITableViewCell扩展几个方法

UITableViewCell+Extension.h

#import <UIKit/UIKit.h>

@interface UITableViewCell (Extension)

//注册cell
+ (void)registerTabelView:(UITableView*)aTable
            nibIdentifier:(NSString*)identifier;

//载入数据
- (void)configure:(UITableViewCell*)aCell
        custimObj:(id)obj
        indexPath:(NSIndexPath*)indexPath;

//根据数据源计算cell高度 默认返回44.0f
+ (CGFloat)getCellHeightWitCustomObj:(id)obj
                           indexPath:(NSIndexPath*)indexPath;

@end

UITableViewCell+Extension.m

#import "UITableViewCell+Extension.h"

@implementation UITableViewCell (Extension)

//注册cell
+ (void)registerTabelView:(UITableView*)aTable
            nibIdentifier:(NSString*)identifier{
    [aTable registerNib:[UINib nibWithNibName:identifier bundle:nil] forCellReuseIdentifier:identifier];
}

//载入数据
- (void)configure:(UITableViewCell*)aCell
        custimObj:(id)obj
        indexPath:(NSIndexPath*)indexPath{
    
}

//根据数据源计算cell高度 默认返回44.0f
+ (CGFloat)getCellHeightWitCustomObj:(id)obj
                           indexPath:(NSIndexPath*)indexPath{
    return 44.0f;
}
@end

在自定义cell的类中重写这两个方法
configure用于数据加载
getCellHeightWitCustomObj用于计算高度

registerTabelView方法在CusetDelegate中用于注册cell到对应tableView


代码中的使用方法

    self.data = [[NSArray alloc]init];

    self.tab = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight) style:UITableViewStylePlain];
    
    TableViewCellConfigureBlock ConfigBlock = ^(NSIndexPath* indexPath,WelfareRuleCell* cell,id item){
        [cell configure:cell custimObj:item indexPath:indexPath];
    };
    TableViewCellDidSelectBlock DidBlock = ^(NSIndexPath* indexPath,id cell,id item){
        
    };
    TableViewCellHeightBlock heightBlock = ^CGFloat(NSIndexPath* indexPath,id item){
        return [WelfareRuleCell getCellHeightWitCustomObj:item indexPath:indexPath];
    };
    
    self.customDelegate = [[CustomDeleagte alloc]initWithItems:_data
                                                cellIdentifier:@"WelfareRuleCell"
                                            configureCellBlock:ConfigBlock
                                               cellHeightBlock:heightBlock
                                                didSelectBlock:DidBlock];
    [self.customDelegate handleTableViewDataSourceAndDelegate:self.tab];
    [self.view addSubview:self.tab];

自定义cell类

#import "WelfareRuleCell.h"

@implementation WelfareRuleCell

- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}

- (void)configure:(UITableViewCell *)aCell custimObj:(id)obj indexPath:(NSIndexPath *)indexPath{
    //数据加载
    self.XXX = XXX;
}

+ (CGFloat)getCellHeightWitCustomObj:(id)obj indexPath:(NSIndexPath *)indexPath{
    //计算高度的代码
    return xxx;
}

@end

后语

使用抽离Delegate和DataSource的方法来使用tableView,控制器中的代码可以被大大的简化,代码逻辑也能更清晰

相关文章

网友评论

  • 蜗牛锅:你好,我按你的写了demo,不能复用,第一次启动时可以正常显示,当上啦时,前面两行就会被隐藏,(self.data = @[@"12",@"22",@"32"];这是我用到测试数据)
    蜗牛锅:@sands_yu 明白了,谢谢哦
    sands_yu:不好意思最近公司比较忙
    我写了一个简单的demo你可以下载下来看看
    https://pan.baidu.com/s/1qYNQd0C

本文标题:代码优化-更精简的tableView,抽离tableView D

本文链接:https://www.haomeiwen.com/subject/iowvwttx.html