HoloCollectionView
HoloCollectionView
提供链式语法调用,封装了 UICollectionView
的代理方法。将 UICollectionView
的代理方法分布到每个 cell
,每个 cell
都有自己的方法来设置类、模型、大小和点击事件等。
特性
- 提供分区和行创建工具以处理
HoloCollectionView
的代理事件。 - 提供在单元格、标题和页脚中实现以处理
HoloCollectionView
代理事件的协议。 - 支持注册行、标题和页脚的映射(键-类)。
- 差异重新加载数据。支持
DeepDiff
的 HoloCollectionViewDiffPlugin - 适配 iOS 13 和 iOS 14 的新 API。
- 支持现代 Objective-C 和更好的 Swift。
示例
要运行示例项目,请克隆仓库,并首先从 Example 目录运行 pod install
与第三方库集成
- HoloCollectionViewDiffPlugin - 支持 DeepDiff,用于对比并重新加载
UICollectionView
的一个部分。DeepDiff
可告知两个集合之间的差异和编辑步骤。
使用方法
1. 创建简单的单元格列表
UICollectionViewFlowLayout *flowLayout = [UICollectionViewFlowLayout new];
flowLayout...
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
[self.view addSubview:collectionView];
[collectionView holo_makeRows:^(HoloCollectionViewRowMaker * _Nonnull make) {
// make a cell
make.row(ExampleCollectionViewCell.class).model(NSDictionary.new).size(CGSizeMake(100, 200));
// make a list
for (NSObject *obj in NSArray.new) {
make.row(ExampleCollectionViewCell.class).model(obj).didSelectHandler(^(id _Nullable model) {
NSLog(@"did select row : %@", model);
});
}
}];
[collectionView reloadData];
// etc.
使用 holo_makeRows:
方法创建行的列表。每个 row
都是一个 cell
。更多行属性见: HoloCollectionViewRowMaker.h 和 HoloCollectionRowMaker.h
单元格要求
遵循协议 HoloCollectionViewCellProtocol
,HoloCollectionView
会自动识别并调用实现了这些方法的 cell
,常用的两个方法是
@required
// set the model to cell
// the model is the object passed in by make.model()
- (void)holo_configureCellWithModel:(id)model;
@optional
// return cell size( Priority is higher than: 'sizeHandler' and 'size' of maker)
// the model is the object passed in by make.model()
+ (CGSize)holo_sizeForCellWithModel:(id)model;
更多方法见 HoloCollectionViewCellProtocol
: HoloCollectionViewCellProtocol
您还可以通过配置如 configSEL
、sizeSEL
等属性来调用您自己的方法。更多属性可以在 HoloCollectionRowMaker.h 中找到。
注意:具有 SEL
的属性,如 size
、shouldHighlight
等,具有优先级。
- 首先判断是否实现了
cell
的sizeSEL
方法 - 其次,验证
sizeHandler
块的实现 - 最后,确定是否已分配
size
属性
2. 制作一个包含标题和页脚的列表行
UICollectionViewFlowLayout *flowLayout = [UICollectionViewFlowLayout new];
flowLayout...
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
[self.view addSubview:collectionView];
[collectionView holo_makeSections:^(HoloCollectionViewSectionMaker * _Nonnull make) {
make.section(TAG)
.header(ExampleHeaderView.class).headerSize(CGSizeMake(HOLO_SCREEN_WIDTH, 100))
.footer(ExampleFooterView.class).footerSize(CGSizeMake(HOLO_SCREEN_WIDTH, 100))
.makeRows(^(HoloCollectionViewRowMaker * _Nonnull make) {
// make a cell
make.row(ExampleCollectionViewCell.class).model(NSDictionary.new).size(CGSizeMake(100, 200));
// make a list
for (NSObject *obj in NSArray.new) {
make.row(ExampleCollectionViewCell.class).model(obj).didSelectHandler(^(id _Nullable model) {
NSLog(@"did select row : %@", model);
});
}
});
}];
[collectionView reloadData];
使用holo_makeSections:
方法来创建一个section
列表。有关更多section属性,请查看:HoloCollectionViewSectionMaker.h和HoloCollectionSectionMaker.h
标题和页脚的要求
- 标题:遵守
HoloCollectionViewHeaderProtocol
协议,实现以下方法,常用的两个方法是
@required
// set the model to header
// the model is the object passed in by make.headerModel()
- (void)holo_configureHeaderWithModel:(id)model;
@optional
// return header size( Priority is higher than: 'headerSizeHandler' and 'headerSize' of maker)
// the model is the object passed in by make.headerModel()
+ (CGSize)holo_sizeForHeaderWithModel:(id)model;
- 页脚:遵守
HoloCollectionViewFooterProtocol
协议,实现以下方法,常用的两个方法是
@required
// set the model to footer
// the model is the object passed in by make.footerModel()
- (void)holo_configureFooterWithModel:(id)model;
@optional
// return footer size( Priority is higher than: 'footerSizeHandler' and 'footerSize' of maker)
// the model is the object passed in by make.footerModel()
+ (CGSize)holo_sizeForFooterWithModel:(id)model;
有关HoloCollectionViewHeaderProtocol
和HoloCollectionViewFooterProtocol
的更多方法请查看:HoloCollectionViewHeaderProtocol和HoloCollectionViewFooterProtocol
您还可以通过配置如headerConfigSEL
,footerConfigSEL
等属性来调用您自己的方法。更多属性可以在HoloCollectionSectionMaker.h中找到。
与cell
一样,包含SEL
的属性也有优先级。
3. Section的方法
// adding
[self.collectionView holo_makeSections:^(HoloCollectionViewSectionMaker * _Nonnull make) {
make.section(TAG);
}];
// inserting at index
[self.collectionView holo_insertSectionsAtIndex:0 block:^(HoloCollectionViewSectionMaker * _Nonnull make) {
make.section(TAG);
}];
// updating with tag value by maker
[self.collectionView holo_updateSections:^(HoloCollectionViewSectionMaker * _Nonnull make) {
make.section(TAG);
}];
// resetting with tag value by maker
[self.collectionView holo_remakeSections:^(HoloCollectionViewSectionMaker * _Nonnull make) {
make.section(TAG);
}];
// deleting
[self.collectionView holo_removeAllSections];
// deleting with tag value
[self.collectionView holo_removeSections:@[TAG]];
// reloadData
[self.collectionView reloadData];
UICollectionView+HoloCollectionView.h
提供了操纵sections
的一系列方法,包括添加、插入、更新、重置、删除等。有关sections的更多方法请查看:UICollectionView+HoloCollectionView.h (section部分)
4. 行的方法
// adding
[self.collectionView holo_makeRows:^(HoloCollectionViewRowMaker * _Nonnull make) {
make.row(ExampleCollectionViewCell.class);
}];
// adding to section with tag value
[self.collectionView holo_makeRowsInSection:TAG block:^(HoloCollectionViewRowMaker * _Nonnull make) {
make.row(ExampleCollectionViewCell.class);
}];
// inserting at index
[self.collectionView holo_insertRowsAtIndex:0 block:^(HoloCollectionViewRowMaker * _Nonnull make) {
make.row(ExampleCollectionViewCell.class);
}];
// inserting at index to section with tag value
[self.collectionView holo_insertRowsAtIndex:0 inSection:TAG block:^(HoloCollectionViewRowMaker * _Nonnull make) {
make.row(ExampleCollectionViewCell.class);
}];
// updating
[self.collectionView holo_updateRows:^(HoloCollectionViewUpdateRowMaker * _Nonnull make) {
make.tag(TAG).size(CGSizeMake(100, 200));
}];
// resetting
[self.collectionView holo_remakeRows:^(HoloCollectionViewUpdateRowMaker * _Nonnull make) {
make.tag(TAG).model(NSDictionary.new).size(CGSizeMake(100, 200));
}];
// deleting
[self.collectionView holo_removeAllRowsInSections:@[TAG]];
// deleting
[self.collectionView holo_removeRows:@[TAG]];
// reloadData
[self.collectionView reloadData];
UICollectionView+HoloCollectionView.h
提供了一系列操作行的方法,包括添加、插入、更新、重置、删除等。有关更多关于行的方法,请参阅:[UICollectionView+HoloCollectionView.h (行部分)](https://github.com/HoloFoundation/HoloCollectionView/blob/ce4a62e040817e520e839583c97db012666d0ca4/HoloCollectionView/Classes/Holo/UICollectionView%2BHoloCollectionView.h#L147-L329)
5. 检索代理
您可以在任何时间检索 UICollectionView
的代理,例如:
// first way
self.collectionView.holo_proxy.dataSource = self;
self.collectionView.holo_proxy.delegate = self;
self.collectionView.holo_proxy.scrollDelegate = self;
// second way
[self.collectionView holo_makeCollectionView:^(HoloCollectionViewViewMaker * _Nonnull make) {
make.dataSource(self).delegate(self).scrollDelegate(self);
}];
一旦设置了 dataSource
、delegate
、scrollDelegate
并实现了它们的一些方法,HoloCollectionView
将首先使用您的方法和返回值。对于具体逻辑,请参阅:[HoloCollectionViewProxy.m](https://github.com/HoloFoundation/HoloCollectionView/blob/master/HoloCollectionView/Classes/HoloProxy/HoloCollectionViewProxy.m)
6. 注册键-类映射
HoloCollectionView
支持预置表头、表尾和行的键值映射。例如:
// regist key-Class map
[self.collectionView holo_makeCollectionView:^(HoloCollectionViewMaker * _Nonnull make) {
make
.makeHeadersMap(^(HoloCollectionViewHeaderMapMaker * _Nonnull make) {
make.header(@"header1").map(ExampleHeaderView1.class);
make.header(@"header2").map(ExampleHeaderView2.class);
// ...
})
.makeFootersMap(^(HoloCollectionViewFooterMapMaker * _Nonnull make) {
make.footer(@"footer1").map(ExampleFooterView1.class);
make.footer(@"footer2").map(ExampleFooterView2.class);
// ...
})
.makeRowsMap(^(HoloTCollectionViewRowMapMaker * _Nonnull make) {
make.row(@"cell1").map(ExampleCollectionViewCell1.class);
make.row(@"cell2").map(ExampleCollectionViewCell2.class);
// ...
});
}];
// use the key value
[self.collectionView holo_makeSections:^(HoloCollectionViewSectionMaker * _Nonnull make) {
// section 1
make.section(TAG1)
.headerS(@"header1")
.footerS(@"footer1")
.makeRows(^(HoloCollectionViewRowMaker * _Nonnull make) {
make.rowS(@"cell1");
make.rowS(@"cell2");
});
// section 2
make.section(TAG2)
.headerS(@"header2")
.footerS(@"footer2")
.makeRows(^(HoloCollectionViewRowMaker * _Nonnull make) {
make.rowS(@"cell1");
make.rowS(@"cell2");
});
// ...
}];
如果事先已注册 key-class
映射,则 headerS
、footerS
和 rowS
会根据注册的映射来获取 Class
。
如果没有注册,headerS
、footerS
、rowS
会直接将传递给它们的字符串转换为 Class
,使用的是 NSClassFromString(NSString * _Nonnull aClassName)
方法。
安装
HoloCollectionView
通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile 中:
pod 'HoloCollectionView'
作者
gonghonglou,[点击发送邮件](/cdn-cgi/l/email-protection#d0b7bfbeb7b8bfheb7bcbfa590b9b3bcbfa5b4feb3bfbd)[email protected]
许可协议
HoloCollectionView遵循MIT许可协议。关于更多详细信息,请参阅LICENSE文件。