Latest 1.1.0
Homepage https://github.com/ShannonChenCHN/YHListKit
License MIT
Platforms ios 7.0, requires ARC
Authors

YHListKit
YHListKit
YHListKit
YHListKit
YHListKit

YHListKit 是一个基于 UICollectionView 的、轻量级的数据驱动列表框架,其核心思想在于通过 Adapter 模式将繁琐的 UICollectionView 相关代理方法转变成数据驱动的接口,更贴近人类的思维方式,同时还将注册 cell 和 dequeue cell 的逻辑封装到了内部。另外,还通过借助消息转发机制,将 UICollectionViewDelegateUIScrollViewDelegate 等代理方法由中间人转发出来,以供外面的业务方在需要时可以使用。

特性

  • 基于 UICollectionView 的适配器,不需要再面对繁琐的 register -> data source -> dequeue 流程
  • 真正的数据驱动
  • 自动缓存 cell/section header/section footer 的高度
  • 使用了面向协议的设计,去耦合
  • 不需要继承,即插即用,无侵入性

预览效果图

YHListKit

架构

YHListKit

原来实现一个列表需要跟 UICollectionView 繁琐的 API 打交道:

  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. 在你的自定义 UICollectionViewCell 中实现 YHCollectionViewCell 协议,手动合成 cellModel 属性(这里以 SCCutomCollectionViewCell 为例):

@interface SCCutomCollectionViewCell : UICollectionViewCell <YHCollectionViewCell>

@end

@implementation SCCutomCollectionViewCell
@synthesize cellModel = _cellModel;

@end

4. 设置 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];

5. 设置 cell 、 section header 和 section footer 的高度的方式有两种,除了在 view model 层设置之外,还可以在对应的 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

Q&A

1. 如何在管理 YHCollectionViewAdapter 的 controller 中与 cells 和 supplementary views 进行通信?

第一步:将 YHCollectionViewAdapterdelegate 属性值设置为当前的 controller;

第二步:实现 YHCollectionViewAdapterDelegate 协议中的方法即可,该协议提供了两个方法分别用来与 cells 和 supplementary views 进行通信:

- (void)collectionViewAdapter:(YHCollectionViewAdapter *)adapter didDequeueCell:(UICollectionViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;

- (void)collectionViewAdapter:(YHCollectionViewAdapter *)adapter didDequeueSupplementaryView:(UICollectionReusableView *)view ofKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;

详见示例代码 Example

2. 如何在管理 YHCollectionViewAdapter 的 controller 中得到 UICollectionViewDelegateUIScrollViewDelete 的方法回调?

第一步:将 YHCollectionViewAdaptercollectionViewDelegate 属性值设置为当前的 controller;

第二步:根据你的需要去实现 UICollectionViewDelegateUIScrollViewDelete 协议中的方法即可。

详见示例代码 Example

安装

YHListKit 可以通过 CocoaPods 安装:

pod 'YHListKit'

也可以通过手动安装,下载源代码后,将 YHListKit 文件夹拖到项目中即可使用。

系统要求

该项目最低支持 iOS 7.0。

TODO

  • [x] 注释和文档
  • [ ] Swift version
  • [x] CocoaPods support
  • [x] Nib Support

致谢❤️

感谢 bestswifterIGListKit 带来的启发。

如果你有好的想法和问题,欢迎提 issue 和 pull request。🤝

许可证

该项目使用的是 MIT 许可证。 详情见 LICENSE 文件。

Latest podspec

{
    "name": "YHListKit",
    "version": "1.1.0",
    "summary": "u4e00u4e2au8f7bu91cfu7ea7u7684u6570u636eu9a71u52a8u5217u8868u6846u67b6u3002A lightweight data-driven list framework for building fast and easy-to-use lists.",
    "description": "YHListKit u662fu4e00u4e2au57fau4e8e UICollectionView u7684u3001u8f7bu91cfu7ea7u7684u6570u636eu9a71u52a8u5217u8868u6846u67b6uff0cu5176u6838u5fc3u601du60f3u5728u4e8eu901au8fc7 Adapter u6a21u5f0fu5c06u7e41u7410u7684 UICollectionView u76f8u5173u4ee3u7406u65b9u6cd5u8f6cu53d8u6210u6570u636eu9a71u52a8u7684u63a5u53e3uff0cu66f4u8d34u8fd1u4ebau7c7bu7684u601du7ef4u65b9u5f0fuff0cu8ba9u521bu5efau590du6742 feeds u6d41u5217u8868u8ddfu5199u914du7f6eu6587u4ef6u4e00u6837 easyu3002",
    "homepage": "https://github.com/ShannonChenCHN/YHListKit",
    "license": "MIT",
    "authors": {
        "ShannonChenCHN": "[email protected]"
    },
    "source": {
        "git": "https://github.com/ShannonChenCHN/YHListKit.git",
        "tag": "v1.1.0"
    },
    "requires_arc": true,
    "screenshots": "https://github.com/ShannonChenCHN/YHListKit/raw/master/src/preview.gif",
    "platforms": {
        "ios": "7.0"
    },
    "source_files": "YHListKit/**/*.{h,m}"
}

Pin It on Pinterest

Share This