YHListKit
是一個基於 UICollectionView
的、輕量級的資料驅動列表框架,其核心思想在於通過 Adapter 模式將繁瑣的 UICollectionView
相關代理方法轉變成資料驅動的介面,更貼近人類的思維方式,同時還將註冊 cell 和 dequeue cell 的邏輯封裝到了內部。另外,還通過藉助訊息轉發機制,將 UICollectionViewDelegate
、UIScrollViewDelegate
等代理方法由中間人轉發出來,以供外面的業務方在需要時可以使用。
特性
- 基於
UICollectionView
的介面卡,不需要再面對繁瑣的 register -> data source -> dequeue 流程 - 真正的資料驅動
- 自動快取 cell/section header/section footer 的高度
- 使用了面向協議的設計,去耦合
- 不需要繼承,即插即用,無侵入性
預覽效果圖
架構
原來建立實現一個列表需要跟 UICollectionView 繁瑣的 API 打交道:
- 建立 UICollectionView;
- 註冊 cell;
- 解析資料/組裝資料;
- 至少實現 3 個代理方法,非常繁瑣;
- reload data;
使用 YHListKit
之後只需要跟資料搞好關係:
- 建立 UICollectionView;
- 解析資料/組裝資料(包含 view model);
- 建立
YHCollectionViewAdapter
,傳入資料,繫結 UICollectionView;- reload data;
程式的本質就是處理資料,UI 是資料的表現層。對於軟體工程師來講,最理想的效果就是寫一個配置檔案,就能看到效果。YHListKit
所做的就是,去掉解析資料之外的多餘步驟,讓我們只需要關心資料,就是這麼簡單。
類、協議 | 功能 |
---|---|
YHCollectionViewCellModel、YHCollectionViewSectionModel | 表徵 cell、 section header 和 section footer 相關資料的 view model |
YHCollectionViewAdapter | 包裝 UICollectionView 代理方法的核心類,將代理回撥形式的介面轉換成 view model 形式的資料驅動介面 |
YHCollectionViewCell、YHCollectionViewSectionHeaderFooter | 定義 cell 和 section header、footer 的通用介面,用來繫結 view model 資料,以及獲取高度 |
MessageInterceptor | 處理訊息轉發的攔截器 |
使用方法
1. 建立 collection view(這一步跟平時使用 UICollectionView
的程式碼一樣):
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds
collectionViewLayout:self.collectionViewLayout]; // 這裡也可以使用自己的 layout
self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.collectionView.backgroundColor = [UIColor colorWithRed:244 green:244 blue:244 alpha:1.0];
self.collectionView.alwaysBounceVertical = YES;
[self.view addSubview:self.collectionView];
複製程式碼
2. 建立 YHCollectionViewAdapter
,繫結 collectionView,設定代理:
self.adapter = [[YHCollectionViewAdapter alloc] init];
self.adapter.collectionView = self.collectionView; // 繫結 collection view
self.adapter.collectionViewDelegate = self; // 設定代理不是必需的,視業務情況而定
self.adapter.delegate = self; // 設定代理不是必需的,視業務情況而定
複製程式碼
3. 設定 view model 資料,也就是建立 section model 和 cell model,配置相關資料(注:這裡僅僅是舉個例子,你可以配置任何你想要展示的資料,只要符合跟示例程式碼中類似的資料結構即可):
// 可以理解為一個 table view 的資料來源由多個 section model 組成,每個 sectionModel 包括 header 和 footer 相關的資訊、cell models、以及 section 本身的資訊。詳見 YHCollectionViewSectionModel 和 YHCollectionViewCellModel 的標頭檔案。
NSMutableArray *sections = [NSMutableArray array];
for (int section = 0; section < 4; section++) {
BOOL hasMultiColumns = section % 2;
// 建立 section model
YHCollectionViewSectionModel *sectionModel = [[YHCollectionViewSectionModel alloc] init];
sectionModel.sectionIdentifier = [NSString stringWithFormat:@"section_id_%@", @(section)]; // 設定 section 的唯一標識,可選
NSMutableArray *rows = [NSMutableArray array];
for (int row = 0; row < 10; row++) {
// 建立 cell model
YHCollectionViewCellModel *cellModel = [[YHCollectionViewCellModel alloc] init];
cellModel.dataModel = [NSString stringWithFormat:@"%i - %i", section, row]; // 設定 model 資料
cellModel.cellClass = [SCCutomCollectionViewCell class]; // 設定 cell class
if (hasMultiColumns) {
cellModel.cellWidth = 160;
cellModel.cellHeight = 160;
} else {
cellModel.cellHeight = 70; // 設定 cell 高度,也可以在對應的 cell 中實現相應的協議方法來實現
}
[rows addObject:cellModel];
}
sectionModel.cellModels = rows; // 設定該 section 的 cell model 集合
sectionModel.headerClass = [SCCollectionSectionHeaderView class]; // 設定 section header 的 class
sectionModel.headerHeight = 50; // 設定 section header 的 高度
sectionModel.footerClass = [SCCollectionSectionFooterView class]; // 設定 section footer 的 class
sectionModel.footerHeight = 20; // 設定 section footer 的 高度
if (hasMultiColumns) {
// 還可以設定 section 的一些佈局引數,比如實現一行兩列的效果
sectionModel.sectionInsets = UIEdgeInsetsMake(10, 20, 10, 20);
sectionModel.minimumLineSpacing = 15;
}
[sections addObject:sectionModel];
}
// 傳入資料
self.adapter.sectionModels = sections;
[self.collectionView reloadData];
複製程式碼
4. 除了在 view model 層設定 cell 、 section header 和 section footer 的高度之外,還可以在對應的 view 層設定高度,只需要實現 YHCollectionViewCell
和 YHCollectionViewSectionHeaderFooter
協議中定義的方法即可:
@protocol YHCollectionViewCell <NSObject>
...
+ (CGFloat)cellHeightWithModel:(YHCollectionViewCellModel *)model;
+ (CGFloat)cellWidthWithModel:(YHCollectionViewCellModel *)model;
@end
複製程式碼
@protocol YHCollectionViewSectionHeaderFooter <NSObject>
...
+ (CGFloat)heightWithModel:(YHCollectionViewSectionModel *)model;
+ (CGFloat)widthWithModel:(YHCollectionViewSectionModel *)model;
@end
複製程式碼
更詳細的使用介紹見示例程式碼 Example。
系統要求
該專案最低支援 iOS 7.0。
TODO
- 完善註釋和文件
- Swift Version
- Carthage Support
致謝❤️
感謝 bestswifter 和 IGListKit 帶來的啟發。
如果你有好的想法和問題,歡迎提 issue 和 pull request。?
許可證
該專案使用的是 MIT 許可證。 詳情見 LICENSE 檔案。