UITableView的简单封装

    初学UITableView,接触了简单的几个项目,也注意到现在大部分项目都在频繁使用这个控件,其重要程度不言而喻。

    UITableView中每个数据往往通过plist来获取,并且通过UITableViewDelegate和UITableViewDataSource这两个协议来完成数据的加载和每一行的样式设计。

    其中需要实现的两个必要的协议分别是:

- tableView:numberOfRowsInSection:
- tableView:cellForRowAtIndexPath:
    前者规定有多少行数据,后者实现每行数据的加载。


    一个标准的有代码复用功能的数据加载如下:

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView * tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    tableView.dataSource = self;
    tableView.delegate = self;
    [self.view addSubview:tableView];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 30;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString * cellName = @"cell";
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellName];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellName];
    }
    return cell;
}

@end

    对每一行cell的Identifier进缓冲池中找,如果有对应的cell则直接拿来使用,如果没有,就重新创建。

    刚开始学习的时候,这段代码几乎就是固定模式了。


    但是这样的代码有一些缺陷:

    1.代码冗余,一个方法里面牵扯到变量定义,赋值等等,虽然实现功能,却不够简洁。

    2.控制器知道的太多了。事实上获取cell的数据只需要获取和传旨两部分,换言之,以最短的两行代码调用实现这个功能,而实现细节最好不要暴露在外部。

    上面的缺陷在自定义cell时候尤为体现。

    这样就提出了一个封装的需求。

    我们把一个cell的数据获取,参数设置都封装在自定义cell内部,而对外部只提供简单的获取cell的方法(一个类方法足以)。

    经过优化,我们得到下面代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TestTableViewCell * cell = [TestTableViewCell cellWithTableView:tableView];
    cell.data = self.data;
    return cell;
}

    这里我们创建了一个TestTableViewCell的自定义类,它继承自UITableViewCell,用来实现对自定义cell的数据获取和设置。

    这里我们没办法看到TestTableViewCell内部是如何实现cell的实力化的,事实上我们也不需要知道,我们需要知道通过这个类的一个类方法cellWithTableView,在传入当前tableView之后就能获取到一个实例化好了的cell。Identifier是对应cell内部自己定义的,我们也不需要去声明和判断。

    第二行代码则是对数据的加载,光实例化好了cell还不够,我们需要传值的方式把数据传到自定义cell类中并完成数据的加载。这里我们传入了一个数据模型,具体的加载方式,imageView加载在哪,Label的宽高是多少,都是封装在类内部的,也不是控制器所关心的事情。

    最后返回这个cell,大功告成。

    同样是设置cell的函数,与上面杂乱的6行代码相比,下面这3行显然要简洁明了很多,并且对代码和功能实现了有效的封装。符合面向对象的编程思想。

    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#import "LHDBaseTableViewCell.h" @interface LHDBaseTableView : UITableView <UITableViewDataSource,UITableViewDelegate> @property (nonatomic, assign) CGFloat cellHeight; @property (nonatomic, assign) BOOL fixed; //是否固定高度 @property (nonatomic, copy) NSInteger(^tableViewNumberOfRowInSection)(UITableView *,NSInteger); @property (nonatomic, copy) UITableViewCell *(^tableViewCellForRowAtIndexPath)(UITableView *, NSIndexPath *); @property (nonatomic, copy) NSInteger(^numberOfSectionInTabelView)(UITableView *); @property (nonatomic, copy) CGFloat(^tableViewHeightForRowAtIndexPath)(UITableView *,NSIndexPath *); @property (nonatomic, copy) BOOL(^tableViewCanEditRowAtIndexPath)(UITableView *,NSIndexPath *); @property (nonatomic, copy) void(^tableViewCommitEditingStyleforRowAtIndexPath)(UITableView *,UITableViewCellEditingStyle,NSIndexPath *); @property (nonatomic, copy) UITableViewCellEditingStyle (^tableViewEditingStyleForRowAtIndexPath)(UITableView *,NSIndexPath *); @property (nonatomic, copy) void(^tableViewDidSelectRowAtIndexPath)(UITableView *,NSIndexPath *); @property (nonatomic, copy) void(^tableViewDidDeselectRowAtIndexPath)(UITableView *,NSIndexPath *); @property (nonatomic, copy) UIView *(^tableViewViewForHeaderInSection)(UITableView *,NSInteger); @property (nonatomic, copy) CGFloat(^tableViewHeightForHeaderInSection)(NSInteger); @property (nonatomic, strong) LHDBaseTableViewCell *myTableViewCell; @property (nonatomic, strong) NSArray *dataArray; - (void)resetDelegate;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值