LCFastBuildListKit
示例
要运行示例项目,请克隆仓库,首先从示例目录运行 pod install
。
需求
安装
LCFastBuildListKit 可以通过 CocoaPods 获得。要安装它,只需将以下行添加到您的 Podfile 中
pod 'LCFastBuildListKit'
作者
jgyhc, [email protected]
许可
LCFastBuildListKit可在MIT许可证下使用。详细信息请参阅LICENSE文件。
LCFastBuildListKit
示例
要运行示例项目,请克隆仓库,首先从示例目录运行 pod install
。
要求
安装
LCFastBuildListKit 可以通过 CocoaPods 获得。要安装它,只需将以下行添加到您的 Podfile 中
pod 'LCFastBuildListKit'
作者
jgyhc, [email protected]
许可
LCFastBuildListKit可在MIT许可证下使用。详细信息请参阅LICENSE文件。
这个库是做什么的?(大佬请绕行)
在日常开发中,我们是否遇到过这样的界面需求,当前界面元素众多,种类繁杂,常见的视图处理方案就是使用UITableView
或者UICollectionView
来实现。于是,我们就在自身体积庞大的ViewController
里开始编写UITableView
的delegate
和dataSource
方法。然后我们可能会看到tableView:cellForRowAtIndexPath:
方法中的代码如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger section = indexPath.section;
if (section == 0) {
if (indexPath.row == 0) {
OrderHeaderCell *cell = [tableView dequeueReusableCellWithIdentifier:@"OrderHeaderCell"];
cell.status = self.data.State;
return cell;
} else {
FBGroupPurchaseCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FBGroupPurchaseCell"];
cell.list = self.productList;
return cell;
}
} else if (section == 2) {
NSArray *arr = self.resultArr[0];
if (arr.count == 0) {
VouchersWaitPayCell *cell = [tableView dequeueReusableCellWithIdentifier:@"VouchersWaitPayCell"];
return cell;
} else {
OrderInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"OrderInfoCell"];
cell.model = arr[indexPath.row];
return cell;
}
} else if (section == 1) {
OrderInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"OrderInfoCell"];
return cell;
} else {
OrderInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"OrderInfoCell"];
NSArray *arr = self.resultArr[section - 2];
cell.model = arr[indexPath.row];
if (section == 3 && indexPath.row == arr.count - 1) {
[cell addline];
}
return cell;
}
}
然后可能是
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger section = indexPath.section;
if (section == 0) {
if (indexPath.row == 0) {
return 60;
} else {
return 105;
}
} else if (section == 1) {
return 0;
} else if (section == 2){
NSArray *arr = self.resultArr[0];
if (arr.count > 0) {
return 30;
} else {
return 110;
}
} else {
return 30;
}
}
对于业务变动不大的场景来说无可厚非,但是一旦需要在页面中增加一个新的Cell
时,缺点就暴露出来了。这个时候发现需要修改的地方有很多,需要对tableView:numberOfRowsInSection:n
、tableView:cellForRowAtIndexPath:
等方法进行修改,而且原来对应的indexPath
都不再适用了。
然后我思考了一下,有没有一种更好的方式来控制这种方式,以便在未来的维护中减少这样的修改呢?
于是,我尝试把tableView
的数据源里装上identifier
来区分cell
,这样我就不再需要考虑因为Cell
顺序改变而对之前编写代码带来的影响。但是后来发现还是不够,我们仍然需要在tableView:cellForRowAtIndexPath:
或者tableView:heightForRowAtIndexPath:
中编写大量的判断逻辑。
为了解决上述困扰,我就尝试封装了一下UITableView
和UICollectionView
的代理方法,统一了对TableViewCell
、CollectionViewCell
、TableViewHeaderView
等对象的描述:
TableViewCell
:
@property (nonatomic, copy) NSString *identifier;
@property (nonatomic, assign) CGFloat cellHeight;
@property (nonatomic, strong) id data;
CollectionViewCell
:
@property (nonatomic, copy) NSString *identifier;
@property (nonatomic, assign) CGSize cellSize;
@property (nonatomic, strong) id data;
TableView
的组:
@property (nonatomic, copy) NSString *headerIdentifier;
@property (nonatomic, copy) NSString *footerIdentifier;
@property (nonatomic, strong) NSArray<ZLTableViewRowModel *> *items;
@property (nonatomic, strong) id headerData;
@property (nonatomic, strong) id footerData;
@property (nonatomic, assign) CGFloat headerHeight;
@property (nonatomic, assign) CGFloat footerHeight;
CollectionView
的组:
@property (nonatomic, copy) NSString *headerIdentifier;
@property (nonatomic, copy) NSString *footerIdentifier;
@property (nonatomic, strong) NSArray<ZLCollectionViewRowModel *> *items;
@property (nonatomic, strong) id headerData;
@property (nonatomic, strong) id footerData;
@property (nonatomic, assign) CGSize headerSize;
@property (nonatomic, assign) CGSize footerSize;
@property (nonatomic, assign) UIEdgeInsets insets;
@property (nonatomic, assign) CGFloat minimumLineSpacing;
@property (nonatomic, assign) CGFloat minimumInteritemSpacing;
看到这里,大家应该都知道我在做什么了吧。。。。虽然不高级,但是使用起来确实方便多了。
统一Cell
的赋值方式和注册方式
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:rowModel.identifier forIndexPath:indexPath];
if ([cell respondsToSelector:@selector(model)] && rowModel.data) {
[cell setValue:rowModel.data forKey:@"model"];
}
对了,Cell
通过model
来接收传递的值。