{"id":18725092,"url":"https://github.com/indulgein/ybhandylist","last_synced_at":"2025-06-17T23:34:41.921Z","repository":{"id":56928833,"uuid":"192519812","full_name":"indulgeIn/YBHandyList","owner":"indulgeIn","description":"让 UITableView / UICollectionView 更加简单优雅，轻易实现列表动态化、模块化、MVVM 架构","archived":false,"fork":false,"pushed_at":"2024-01-19T08:34:18.000Z","size":120,"stargazers_count":162,"open_issues_count":10,"forks_count":22,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-12-07T18:29:34.239Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/indulgeIn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-18T10:39:22.000Z","updated_at":"2024-10-31T17:37:59.000Z","dependencies_parsed_at":"2022-08-21T06:20:28.879Z","dependency_job_id":null,"html_url":"https://github.com/indulgeIn/YBHandyList","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indulgeIn%2FYBHandyList","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indulgeIn%2FYBHandyList/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indulgeIn%2FYBHandyList/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/indulgeIn%2FYBHandyList/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/indulgeIn","download_url":"https://codeload.github.com/indulgeIn/YBHandyList/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230431103,"owners_count":18224655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T14:09:02.954Z","updated_at":"2024-12-19T12:10:33.726Z","avatar_url":"https://github.com/indulgeIn.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# YBHandyList\n\n[![Cocoapods](https://img.shields.io/cocoapods/v/YBHandyList.svg)](https://cocoapods.org/pods/YBHandyList)\u0026nbsp;\n[![Cocoapods](https://img.shields.io/cocoapods/p/YBHandyList.svg)](https://github.com/indulgeIn/YBHandyList)\u0026nbsp;\n[![License](https://img.shields.io/github/license/indulgeIn/YBHandyList.svg)](https://github.com/indulgeIn/YBHandyList)\u0026nbsp;\n\n\n让 UITableView / UICollectionView 更加简单优雅，轻易实现列表动态化、模块化、MVVM 架构。\n\n原理分析文章：[iOS 列表界面如何优雅实现模块化与动态化](https://www.jianshu.com/p/f0a74d5744b8)\n\n## 特性\n\n- 列表动态化、列表模块化\n- 为实施 MVVM 架构提供支撑\n- IOP 思想，接入或弃用都随心所欲，不拖泥带水\n- 无技术难点，轻量化设计，可支持全量的原生功能\n\n\n## 安装\n\n### CocoaPods\n\n1. 在 Podfile 中添加 `pod 'YBHandyList'`。\n2. 执行 `pod install` 或 `pod update`。\n3. 导入 `\u003cYBHandyList/YBHandyList.h\u003e`。\n\n若搜索不到库，可使用 rm ~/Library/Caches/CocoaPods/search_index.json 移除本地索引然后再执行安装，或者更新一下 CocoaPods 版本。\n\n### 手动导入\n\n1. 下载 YBHandyList 文件夹所有内容并且拖入你的工程中。\n2. 导入 `YBHandyList.h`。\n\n\n## 用法\n\n可下载 DEMO 查看示例。\n\n核心思路：UITableView / UICollectionView 的每一个 Cell / Header / Footer 都对应一个 Config 对象，Cell / Header / Footer 和其对应的 Config 对象都需要实现相应的协议。 \n\n### 简洁使用\n\n组件默认实现了一系列 Config 对象（`YBHTableCellConfig / YBHCollectionCellConfig`等），可以直接使用：\n\n```\nYBHTableCellConfig *config0 = [YBHTableCellConfig new];\nconfig0.model = ...;\nconfig0.cellClass = TestTableCell.self;\n\nYBHTableCellConfig *config1 = [YBHTableCellConfig new];\nconfig1.model = ...;\nconfig1.cellClass = TestTableCell.self;\n\n//赋值并刷新\n[self.tableView.ybht_rowArray addObjectsFromArray:@[config0, config1]];\n[self.tableView reloadData];\n```\n同时，Cell / Header / Footer 中需要实现对应的协议：\n```\n@implementation TestTableCell\n#pragma mark - \u003cYBHTableCellProtocol\u003e\n- (void)ybht_setCellConfig:(id\u003cYBHTableCellConfig\u003e)config {\n    //根据 config 对象拿到数据做业务处理\n    ... = config.ybht_model;\n}\n+ (CGFloat)ybht_heightForCellWithConfig:(nonnull id\u003cYBHTableCellConfig\u003e)config reuseIdentifier:(nonnull NSString *)reuseIdentifier indexPath:(nonnull NSIndexPath *)indexPath {\n    //返回当前 cell 的高度\n    return UITableViewAutomaticDimension;\n}\n@end\n```\n当然，对于 Config 对象你可以自定义，只需要实现了 Config 相关的协议就行了。\n\n\n### Cell / Header / Footer 事件和数据传递\n\n由于 Cell / Header / Footer 被抽象出来了，外界与它们联系的最好方式是通过 Config 对象 （或其属性）。通过 Config 对象（或其属性）持有一个代理对象 Delegate，然后在 Cell / Header / Footer 里面通过 Delegate 向外界传递事件和数据。\n\n笔者建议的方式是自定义 Config 类，只需要实现对应的协议（或者继承组件默认实现的 Config 类）。\n\n这部分具体的看 Demo。\n\n\n### 如何实现更多的 UITableView / UICollectionView 代理方法？\n\n组件做的事情不过是对 UITableView / UICollectionView 的代理方法进行了封装（核心类：`YBHandyTableIMP / YBHandyCollectionIMP`），然后对外暴露了数组来配置，所以难免会有一些未实现的代理方法。\n\n你只需要继承 `YBHandyTableIMP / YBHandyCollectionIMP` 类，然后在这个子类里面随心所欲的实现任何代理方法，并且可以覆盖父类的实现。然后，将这个子类赋值给`self.tableView.ybht_tableIMP`属性；你甚至可以直接将 UITableView / UICollectionView 的代理设置为这个`IMP`子类。\n\n`UITableView+YBHandyList`和`UICollectionView+YBHandyList`都是语法糖而已，组件的核心就是一个代理实现类，非常简单。\n\n\n### 如何在 MVVM 架构上实施？\n\nDemo 中有个简单的案例。\n\n实际上 MVVM 架构中的 ViewModel 完全可以作为前面所说的 Config 对象，只需要 ViewModel 实现 Config 协议就行了，然后每一个 Cell / Header / Footer 对应一个 ViewModel。\n\n**组件对架构是无感知的，IOP 模式让它能在大部分场景无障碍实施。**\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Findulgein%2Fybhandylist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Findulgein%2Fybhandylist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Findulgein%2Fybhandylist/lists"}