要说 iOS 开发中有什么是最离不开的组件,我想是 UITableViewController。几乎每个iPhone 应用都会有它的身影,用了它,,不用考虑内容过多的问题,,熟悉自定义 UITableViewCell 之后,用起来几乎和 UITableViewController 没啥差。
基本上,我认为所有能用 UITableViewController 实现的页面都该是UITableViewController,使用它的好处有:
- 自带 ScrollView,不用考虑内容过多显示不全、尺寸差异等问题
- 使用 DataSource 返回数据,使用 Delegate 设置 Cell 的属性
然后在使用在使用这些好处的时候,很容易就会发生 Controller 承载太多的功能:
- DataSource、Delegate 的实现
- 创建 Cell 在 Controller
- 布局 Cell 代码
- 获取 Cell 需要的数据
- 网络请求
……简直包山包海。
然后就有了 、 这种最佳实践文章。
这篇文章的观点是把 DataSource 分离出来,独立成一个类,然后将 tableView 的 dataSource 属性指给其实例,如:
- (void)viewDidLoad{ self.tableView.dataSource = [[MenuDataSouirce alloc] initWithItems:@[@"用户", @"问题", @"文章", @"标签", @"登录"]]; ....}
接下来就是在 dataSource 中创建Cell、设置样式、填充数据,在 Controller 中实现了 delegate,一切仿佛都变的好了简洁了又可以爱下去了。
随着项目的进行,会发现有很多「无趣」的页面都要做重复的工作,如侧边栏、用户设置、用户登录页这种,每次都要去实现一遍 dataSource 里面的这些方法:
tableView:cellForRowAtIndexPath: tableView:numberOfRowsInSection: tableView:numberOfSection:
WTF!!你发现这些堆代码的工作消耗了很多时间,而这些无聊工作应该更快更好的完成。
如果你遇到相同的苦恼,SSDataSources 或许能把你解救出来。
SSDataSources 都能做什么呢?它由以下部分组成:
- SSArrayDataSource:基本的 DataSource,初始化的时候设置一波元素,没有Section,不能展开
- SSExpandingDataSource:页面元素可以展开
- SSSectionedDataSource:页面元素具有分组样式
不管哪一种类型,SSDataSources 都支持动态增加元素、删除元素。此外它也同时适用于 UICollectionView。还有一些对 FooterView、HeaderView 的冗余属性,总之让你和 tableView 打交道的时候更舒心。
下面贴一下使用 SSDataSource 实现的侧边栏(代码还不到 50 行):
#import "MenuController.h"#import "SSArrayDataSource.h"#define TOP_CELL_HEIGHT 64.0f@interface MenuController ()@property (nonatomic, strong) SSArrayDataSource *dataSource;@property (nonatomic, strong) NSArray *items;@end@implementation MenuController{}- (void)viewDidLoad{ [super viewDidLoad]; self.items = @[ @"用户", @"问题", @"文章", @"标签", @"", @"登录"]; self.dataSource = (id)[[SSArrayDataSource alloc] initWithItems:self.items]; [self.dataSource setCellConfigureBlock:^(UITableViewCell *cell, NSString *s, id parentView, NSIndexPath *indexPath) { cell.textLabel.text = s; }]; self.tableView.dataSource = self.dataSource;}- (CGFloat) tableView:(UITableView *)tableViewheightForRowAtIndexPath:(NSIndexPath *)indexPath{ CGFloat result = 44; if(indexPath.row == 0) { result = TOP_CELL_HEIGHT; } else if([self.items[(NSUInteger) indexPath.row] isEqualToString:@""]) { CGFloat screen_height = self.view.bounds.size.height; CGFloat other_hight_sum = TOP_CELL_HEIGHT + (self.items.count-2) * 44.f; result = MAX(screen_height - other_hight_sum, 0.f); } return result;}@end
效果图:
什么?心动了?赶快打开浏览器去看看吧: