文档章节

iOS开发 - UITableview代理方法与Viewcontroller分离

resory
 resory
发布于 2015/12/31 10:20
字数 857
阅读 656
收藏 15

#序

在objcio.cn中有一篇文章更轻量的 View Controllers.其中有一小节,是说把UITableview的datasource和delegate分离出Viewcontroller的。我也试着实现了一下,随便把思路总结下~

DEMO


建议先下载demo,再结合下面的分析,会好理解点。地址https://github.com/Resory/RYDatasource

逻辑


  • 既然我们要把UITableview的协议方法分离出来,就得有一个人去接,在这里我们把这个人叫Datasource。可以理解它为中间人。这个中间人就是以后实现UITableview协议方法的地方。

  • 中间人实现UITableview协议方法,就得知道UITableview的数据复用事件等要素。这些数据由Viewcontroller来传。这三个要素分别定义为serverDatacellIdentifiersconfigSelectedBlock

  • 自此我们可以知道,只要Viewcontroller传了serverDatacellIdentifiersconfigSelectedBlock这三个基本参数,中间人就可以实现UITableview协议方法了。

实现


  • 在Viewcontroller.m中。我们命名了三个全局变量,如下代码 (configSelectedBlock不需要设置全局,到时候在函数中直接生成即可)
// Viewcontroller.m
@property (nonatomic, strong) NSMutableArray *serverData;       // 服务器返回的数据
@property (nonatomic, strong) NSMutableArray *cellIdentifiers;  // cell样式标示
@property (nonatomic, strong) TDatasource *datasource;          // 中间人
  • 还是在Viewcontroller.m中.我们把数据,复用,事件设置好后,看看如何调用中间人
数据
// Viewcontroller.m  
- (void)configData
{
    // 服务器返回的数据
    _serverData = [[NSMutableArray alloc] init];
    // 实体设置
    TModelOne *one = [[TModelOne alloc] init];
    TModelOne *two = [[TModelOne alloc] init];
    
    one.name = @"奇犽";
    one.imageName = @"001.jpg";
    
    two.name = @"拿尼加";
    two.imageName = @"002.jgp";
    
    [_serverData addObject:one];
    [_serverData addObject:two];
}
复用
// Viewcontroller.m  
- (void)configIdentifier
{
    // cell复用设置
    _cellIdentifiers = [[NSMutableArray alloc] init];
    [_cellIdentifiers addObject:NSStringFromClass([TCellOne class])];
    [_tableview registerNib:[TCellOne nib] forCellReuseIdentifier:_cellIdentifiers[0]];
}
初始化"中间人"
// Viewcontroller.m  
- (void)configDataSource
{
    // cell数据
    [self configData];
    
    // cell复用
    [self configIdentifier];
    
    // cell事件
    RYCellSelectedBlock cellSelectedBlock = ^(id obj){
        // cell点击事件
        [self cellSelectedWithObj:obj];
    };
    
    // 初始化dataSource
    _datasource = [[TDatasource alloc] initWithServerData:_serverData
                                       andCellIdentifiers:_cellIdentifiers];
    _datasource.cellSelectedBlock = cellSelectedBlock;
}
  • 中间人设置为UITableview的协议方法执行者
// Viewcontroller.m  
- (void)configTableView
{
    // 把_dataSource设置成_tableview的代理,以后所有代理方法都在_dataSource实现
    _tableview.delegate = _datasource;
    _tableview.dataSource = _datasource;
    _tableview.tableFooterView = [UIView new];
}
  • 我们进去中间人看看它到底做了什么,下面的代码可以清晰看到。中间人除了多了初始化方法来接受数据外,其他方法都是UITableview的协议方法

// TDatasource.m

- (id)initWithServerData:(NSArray *)serverData
      andCellIdentifiers:(NSArray *)identifiers
{
    self = [super init];
    if(self)
    {
        self.serverData = serverData;           // 数据
        self.cellIdentifiers = identifiers;     // 复用
    }
    
    return self;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifiers[0]
                                                            forIndexPath:indexPath];
    // cell的数据填充(cell的category方法)
    [cell configCellWithEntity:self.serverData[indexPath.row]];
    
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 80.0;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // cell点击事件
    self.cellSelectedBlock(indexPath);
}

  • 最后我们来看下cell里面的方法,也是一眼能看懂的代码··

#import "TCellOne.h"
#import "TModelOne.h"

@implementation TCellOne

- (void)awakeFromNib {
    // Initialization code
}

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

    // Configure the view for the selected state
}

- (void)configCellWithEntity:(id)entity
{
    if(entity)
    {
        TModelOne *model = entity;
        self.name.text = model.name;
        self.avartar.image = [UIImage imageNamed:model.imageName];
    }
}
  • 挫就挫吧,总得来张图。。

奇犽~.png #最后

  • UITableview协议方法分离出Viewcontroller后,Viewcontroller确实清爽了不少。但同时也带了不便,比如说又多了一个文件,又比如说cell的点击事件就得用一个block来回调,如果是cell里面的子view的点击事件就更不利索了。所以有利就有弊吧。还是得结合实际选择最适合自己的开发方式~

  • 如果你有疑问或者发现错误请留言给我

  • 喜欢就点个赞,点个星什么的。3Q~~

© 著作权归作者所有

resory
粉丝 11
博文 34
码字总数 12055
作品 0
深圳
程序员
私信 提问
加载中

评论(10)

明德丶o
明德丶o
i
明德丶o
明德丶o
13
resory
resory

引用来自“CrazyPeter”的评论

基本框架已经有了,再把cell高度自定义一个数组,就更加完美了。

引用来自“开源中国X科长”的评论

这位高见,我已觉得快速滚动会发热, datasource应该用NSCache+JsonModel去做磁盘缓存 后台NStimer会轮训是否有新的pull条数插入到datasouce
如果是我自己的话,我只会更新一下serverdata的数据来然后reloaddata刷新数据。
开源中国射线科科长
开源中国射线科科长

引用来自“CrazyPeter”的评论

基本框架已经有了,再把cell高度自定义一个数组,就更加完美了。
这位高见,我已觉得快速滚动会发热, datasource应该用NSCache+JsonModel去做磁盘缓存 后台NStimer会轮训是否有新的pull条数插入到datasouce
开源中国射线科科长
开源中国射线科科长
在尝试自己写一个TBView APL的循环利用原理已经天下皆知 目前的难度是 如何绑定时间 最好是不是用OOP 混合是用IOC 用插入block的方式去操作更加先进的 collectionView 毕竟 tableview只不过是宽高固定的collectionView罢了

http://git.oschina.net/stdk-sting/LFTableView_Demo
resory
resory

引用来自“iDalink”的评论

为什么不把ViewController作为TableView的dataSource?为什么加一个DataSource类?
传统的Tableview协议方法是写在ViewController中的,但是随着ViewController代码越来越多,所以就有人想到把ViewController的部分代码分离出来,TableView的协议方法就是分离的一个方向。当然,分不分离都是因人而异,没有最好的代码,只有最合适的代码
iDalink
iDalink
为什么不把ViewController作为TableView的dataSource?为什么加一个DataSource类?
resory
resory

引用来自“CrazyPeter”的评论

基本框架已经有了,再把cell高度自定义一个数组,就更加完美了。
其实我是这么想的。cell高度自定义,可以直接写在datasource中,并不需要再从viewcontroller中传数组过去。
CrazyPeter
CrazyPeter
基本框架已经有了,再把cell高度自定义一个数组,就更加完美了。
MZHS
MZHS
编程就应该这样,逻辑清晰,各个类,各个对象各司其职
iOS开发tips-神奇的UITableView

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jianxin160/article/details/71436920 概述 UITableView是iOS开发中使用频率最高的UI控件,在前面的文章中对于...

KenshinCui
2017/05/08
0
0
tablevView 的跳转问题

// // ViewController.m // ios-TabelView // // Created by ma c on 15/8/28. // Copyright (c) 2015年 sxt. All rights reserved. // #import "ViewController.h" #import "Second.h" @in......

july_toy
2015/09/09
162
2
ITableView最简单的用法(CHGAdapter)

UITableView编程之现阶段的问题 做ios开发的同学都知道使用UITableView开发的时候必须实现其dataSource、delegate两个协议,并且需要实现其相应的方法,感觉还算简单。但是随着开发的深入越来...

萤火的萤火
2018/08/31
0
0
iOS开发小技巧:刷新UITableView

在很多APP界面都用到的UITableView,对iOS开发者来说一定不陌生吧。网上关于UITableView的文章早已多不胜数,尤其是关于UITableView优化方面的,对开发者来说非常值得一看。 现在就来看看,刷...

flyurt
2015/10/23
1K
0
iOS开发tips-UITableView、UICollectionView行高/尺寸自适应

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jianxin160/article/details/55002487 UITableView 我们都知道UITableView从iOS 8开始实现行高的自适应相对比...

KenshinCui
2017/02/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Tedis:基于 TiKV 构建的 NoSQL 数据库

作者介绍: 陈东明,饿了么北京技术中心架构组负责人,负责饿了么的产品线架构设计以及饿了么基础架构研发工作。曾任百度架构师,负责百度即时通讯产品的架构设计。具有丰富的大规模系统构 ...

TiDB
17分钟前
0
0
linux命令

ls命令是linux下最常用的命令。ls命令就是list的缩写,缺省下ls用来打印出当前目录的清单。如果ls指定其他目录,那么就会显示指定目录里的文件及文件夹清单。 通过ls 命令不仅可以查看linux文件...

WinkJie
25分钟前
0
0
你需要的物流运输类报表,这里都有

你需要的物流运输类报表,都在这里 葡萄城报表模板库是一款免费的报表制作、学习和参考工具,包含了超过 200 张高质量报表模板,涵盖了 16 大行业和 50 多种报表类型,为 30 余万报表开发者提...

葡萄城技术团队
32分钟前
1
0
像Java SE一样编写Java EE(ddd探索)

今天主要改写昨天的组合模式成Web系统。 容器接口为 public interface TreeProduct { /** * 展示所有产品 * @return */ List<TreeProduct> allProducts();...

算法之名
33分钟前
0
0
Django Model 模型建立

Django Model 模型 Django Model层是Django的数据模型层,每一个Model类就是数据库中的一张表; 我们需要注意下面几点: model一般都是定义在不同的APP的models.py模块文件中,可以是一个,也...

彩色泡泡糖
41分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部