一個輕量級的數據驅動列表框架 YHListKit

GitHub 源碼地址git

YHListKit 是一個基於 UICollectionView 的、輕量級的數據驅動列表框架,其核心思想在於經過 Adapter 模式將繁瑣的 UICollectionView 相關代理方法轉變成數據驅動的接口,更貼近人類的思惟方式,同時還將註冊 cell 和 dequeue cell 的邏輯封裝到了內部。另外,還經過藉助消息轉發機制,將 UICollectionViewDelegateUIScrollViewDelegate 等代理方法由中間人轉發出來,以供外面的業務方在須要時可使用。github

特性

  • 基於 UICollectionView 的適配器,不須要再面對繁瑣的 register -> data source -> dequeue 流程
  • 真正的數據驅動
  • 自動緩存 cell/section header/section footer 的高度
  • 使用了面向協議的設計,去耦合
  • 不須要繼承,即插即用,無侵入性

預覽效果圖

架構

原來建立實現一個列表須要跟 UICollectionView 繁瑣的 API 打交道:swift

  1. 建立 UICollectionView;
  2. 註冊 cell;
  3. 解析數據/組裝數據;
  4. 至少實現 3 個代理方法,很是繁瑣;
  5. reload data;

使用 YHListKit 以後只須要跟數據搞好關係:緩存

  1. 建立 UICollectionView;
  2. 解析數據/組裝數據(包含 view model);
  3. 建立 YHCollectionViewAdapter,傳入數據,綁定 UICollectionView;
  4. 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 層設置高度,只須要實現 YHCollectionViewCellYHCollectionViewSectionHeaderFooter 協議中定義的方法便可:

@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

致謝❤️

感謝 bestswifterIGListKit 帶來的啓發。佈局

若是你有好的想法和問題,歡迎提 issue 和 pull request。🤝spa

許可證

該項目使用的是 MIT 許可證。 詳情見 LICENSE 文件。設計

相關文章
相關標籤/搜索