├── .DS_Store ├── .gitignore ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── LICENSE ├── Package.swift ├── README.md ├── Tests ├── LinuxMain.swift └── ZHTableViewGroupTests │ ├── XCTestManifests.swift │ └── ZHTableViewGroupTests.swift ├── ZHTableViewGroupExample ├── ZHTableViewGroupExample.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── ZHTableViewGroupObjc.xcscheme ├── ZHTableViewGroupExample │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── HiddenViewController.h │ ├── HiddenViewController.m │ ├── Info.plist │ ├── ReloadCellDataViewController.h │ ├── ReloadCellDataViewController.m │ ├── ReloadCellViewController.h │ ├── ReloadCellViewController.m │ ├── ReloadHeightViewController.h │ ├── ReloadHeightViewController.m │ ├── SceneDelegate.h │ ├── SceneDelegate.m │ ├── SetHeightViewController.h │ ├── SetHeightViewController.m │ ├── TableViewController.h │ ├── TableViewController.m │ ├── TableViewController.xib │ ├── ViewController.h │ ├── ViewController.m │ └── main.m └── ZHTableViewGroupObjc │ ├── Info.plist │ ├── ZHAutoConfigurationCollectionViewDelegate.h │ ├── ZHAutoConfigurationCollectionViewDelegate.m │ ├── ZHAutoConfigurationTableViewDelegate.h │ ├── ZHAutoConfigurationTableViewDelegate.m │ ├── ZHCollectionViewBaseModel.h │ ├── ZHCollectionViewBaseModel.m │ ├── ZHCollectionViewCell.h │ ├── ZHCollectionViewCell.m │ ├── ZHCollectionViewDataSource.h │ ├── ZHCollectionViewDataSource.m │ ├── ZHCollectionViewGroup.h │ ├── ZHCollectionViewGroup.m │ ├── ZHCollectionViewHeaderFooter.h │ ├── ZHCollectionViewHeaderFooter.m │ ├── ZHTableViewBaseModel.h │ ├── ZHTableViewBaseModel.m │ ├── ZHTableViewCell.h │ ├── ZHTableViewCell.m │ ├── ZHTableViewDataSource.h │ ├── ZHTableViewDataSource.m │ ├── ZHTableViewGroup.h │ ├── ZHTableViewGroup.m │ ├── ZHTableViewGroupObjc.h │ ├── ZHTableViewHeaderFooter.h │ ├── ZHTableViewHeaderFooter.m │ └── include │ ├── ZHAutoConfigurationCollectionViewDelegate.h │ ├── ZHAutoConfigurationTableViewDelegate.h │ ├── ZHCollectionViewBaseModel.h │ ├── ZHCollectionViewCell.h │ ├── ZHCollectionViewDataSource.h │ ├── ZHCollectionViewGroup.h │ ├── ZHCollectionViewHeaderFooter.h │ ├── ZHTableViewBaseModel.h │ ├── ZHTableViewCell.h │ ├── ZHTableViewDataSource.h │ ├── ZHTableViewGroup.h │ ├── ZHTableViewGroupObjc.h │ └── ZHTableViewHeaderFooter.h ├── ZHTableViewGroupObjc.podspec └── images ├── 2019-08-20-034515.png ├── 2019-08-20-035055.png ├── image-20190820115521632.png ├── image-20190820115538881.png ├── image-20190820115647037.png └── image-20190820115743952.png /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josercc/ZHTableViewGroup/30d5a4246d49d70bfeb3465ad6fe931bbbe7acf2/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | Carthage 26 | # We recommend against adding the Pods directory to your .gitignore. However 27 | # you should judge for yourself, the pros and cons are mentioned at: 28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 29 | # 30 | # Note: if you ignore the Pods directory, make sure to uncomment 31 | # `pod install` in .travis.yml 32 | # 33 | # Pods/ 34 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 15038777234 <15038777234@163.com> 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.2 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "ZHTableViewGroup", 8 | products: [ 9 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 10 | .library( 11 | name: "ZHTableViewGroup", 12 | targets: ["ZHTableViewGroup"]), 13 | ], 14 | dependencies: [ 15 | // Dependencies declare other packages that this package depends on. 16 | // .package(url: /* package url */, from: "1.0.0"), 17 | ], 18 | targets: [ 19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 20 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 21 | .target( 22 | name: "ZHTableViewGroup", 23 | dependencies: [], 24 | path:"ZHTableViewGroupExample/ZHTableViewGroupObjc"), 25 | .testTarget( 26 | name: "ZHTableViewGroupTests", 27 | dependencies: ["ZHTableViewGroup"]), 28 | ] 29 | ) 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | filename:images 3 | --- 4 | 5 | 6 | 7 | ## Swift 版本请移步[这里](https://github.com/josercc/SwiftTableViewGroup) 8 | 9 | `ZHTableViewGroup`为 `UITableView`和 `UICollectionView` 而生 10 | 11 | ## 演示 12 | 13 | ### 简单的列表 14 | 15 | ![image-20200928175235608](https://gitee.com/joser_zhang/upic/raw/master/uPic/image-20200928175235608.png) 16 | 17 | ```objc 18 | ZHTableViewDataSource *dataSource = [[ZHTableViewDataSource alloc] initWithTableView:self.tableView]; 19 | [dataSource clearData]; 20 | [dataSource addGroupWithCompletionHandle:^(ZHTableViewGroup * _Nonnull group) { 21 | [group addCellWithCompletionHandle:^(ZHTableViewCell *tableViewCell) { 22 | tableViewCell.anyClass = [UITableViewCell class]; 23 | tableViewCell.identifier = @"UITableViewCell"; 24 | NSArray *titles = @[@"刷新高度",@"刷新Cell",@"刷新数据",@"显示和隐藏"]; 25 | tableViewCell.cellNumber = titles.count; 26 | [tableViewCell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 27 | cell.textLabel.text = titles[indexPath.row]; 28 | }]; 29 | }]; 30 | }]; 31 | [dataSource reloadTableViewData]; 32 | ``` 33 | 34 | ### 动态刷新高度 35 | 36 | ![image-20200928175932428](https://gitee.com/joser_zhang/upic/raw/master/uPic/image-20200928175932428.png) 37 | 38 | ```objc 39 | [self.tableViewDataSource clearData]; 40 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 41 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 42 | self->_weakCell = cell; 43 | cell.anyClass = [ReloadHeightCell1 class]; 44 | cell.identifier = @"ReloadHeightCell1"; 45 | [cell setConfigCompletionHandle:^(ReloadHeightCell1 *cell1, NSIndexPath *indexPath) { 46 | cell1.textLabel.text = @"ReloadHeightCell1"; 47 | }]; 48 | }]; 49 | }]; 50 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 51 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 52 | cell.anyClass = [ReloadHeightCell2 class]; 53 | cell.identifier = @"ReloadHeightCell2"; 54 | cell.cellNumber = 2; 55 | [cell setConfigCompletionHandle:^(ReloadHeightCell2 *cell1, NSIndexPath *indexPath) { 56 | cell1.textLabel.text = @"ReloadHeightCell2"; 57 | }]; 58 | }]; 59 | }]; 60 | [self.tableViewDataSource reloadTableViewData]; 61 | ``` 62 | 63 | #### identifier更新自动高度 64 | 65 | ```objc 66 | [self.tableViewDataSource reloadCellAutomaticHeightWithIdentifier:@"ReloadHeightCell1"] 67 | ``` 68 | 69 | #### identifier更新固定250高度 70 | 71 | ```objc 72 | [self.tableViewDataSource reloadCellFixedHeight:250 identifier:@"ReloadHeightCell1"] 73 | ``` 74 | 75 | #### Class更新自动高度 76 | 77 | ```objc 78 | [self.tableViewDataSource reloadCellAutomaticHeightWithClass:NSClassFromString(@"ReloadHeightCell1")] 79 | ``` 80 | 81 | #### Class更新固定260高度 82 | 83 | ```objc 84 | [self.tableViewDataSource reloadCellFixedHeight:260 className:NSClassFromString(@"ReloadHeightCell1")] 85 | ``` 86 | 87 | #### 指定ZHTableViewCell更新自动高度 88 | 89 | ```objc 90 | [self.tableViewDataSource reloadCellAutomaticHeightWithTableViewCell:self.tableViewDataSource.groups[0].cells[0]] 91 | ``` 92 | 93 | #### 指定ZHTableViewCell更新固定270高度 94 | 95 | ```objc 96 | [self.tableViewDataSource reloadCellFixedHeight:270 tableViewCell:self.tableViewDataSource.groups[0].cells[0]] 97 | ``` 98 | 99 | #### 指定索引更新自动高度 100 | 101 | ```objc 102 | [self.tableViewDataSource reloadCellAutomicHeightWithGroupIndex:1 cellIndex:0] 103 | ``` 104 | 105 | #### 指定索引更新固定280高度 106 | 107 | ```objc 108 | [self.tableViewDataSource reloadCellFixedHeight:280 groupIndex:1 cellIndex:0] 109 | ``` 110 | 111 | ### 刷新值 112 | 113 | ![image-20200928180955425](https://gitee.com/joser_zhang/upic/raw/master/uPic/image-20200928180955425.png) 114 | 115 | ```objc 116 | [self.tableViewDataSource clearData]; 117 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 118 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 119 | cell.anyClass = [UITableViewCell class]; 120 | cell.identifier = @"UITableViewCell"; 121 | [cell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 122 | cell.textLabel.text = [@(random() % 99 + 1) stringValue]; 123 | }]; 124 | }]; 125 | }]; 126 | [self.tableViewDataSource reloadTableViewData]; 127 | ``` 128 | 129 | #### 通过Identifier刷新 130 | 131 | ```objc 132 | [self.tableViewDataSource reloadCellWithIdentifier:@"UITableViewCell"] 133 | ``` 134 | 135 | #### 通过Class刷新 136 | 137 | ```objc 138 | [self.tableViewDataSource reloadCellWithClassName:[UITableViewCell class]] 139 | ``` 140 | 141 | #### 通过指定UITableViewCell更新 142 | 143 | ```objc 144 | [self.tableViewDataSource reloadCellWithTableViewCell:self.tableViewDataSource.groups[0].cells[0]] 145 | ``` 146 | 147 | #### 通过索引更新 148 | 149 | ```objc 150 | [self.tableViewDataSource reloadCellWithGroupIndex:0 cellIndex:0] 151 | ``` 152 | 153 | ### 刷新个数 154 | 155 | ![image-20200928181349639](https://gitee.com/joser_zhang/upic/raw/master/uPic/image-20200928181349639.png) 156 | 157 | ```objc 158 | _randoms = [NSMutableArray arrayWithArray:@[@"random"]]; 159 | [self.tableViewDataSource clearData]; 160 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 161 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 162 | cell.anyClass = [UITableViewCell class]; 163 | cell.identifier = @"UITableViewCell"; 164 | cell.cellNumber = _randoms.count; 165 | [cell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 166 | cell.textLabel.text = _randoms[indexPath.row]; 167 | }]; 168 | }]; 169 | }]; 170 | [self.tableViewDataSource reloadTableViewData]; 171 | ``` 172 | 173 | #### identifier刷新个数 174 | 175 | ```objc 176 | [self.tableViewDataSource reloadCellWithDataCount:_randoms.count identifier:@"UITableViewCell"] 177 | ``` 178 | 179 | #### Class刷新个数 180 | 181 | ```objc 182 | [self.tableViewDataSource reloadCellWithDataCount:_randoms.count className:[UITableViewCell class]] 183 | ``` 184 | 185 | #### UITableViewCell刷新个数 186 | 187 | ```swift 188 | [self.tableViewDataSource reloadCellWithDataCount:_randoms.count tableViewCell:self.tableViewDataSource.groups[0].cells[0]] 189 | ``` 190 | 191 | #### 索引刷新个数 192 | 193 | ```objc 194 | [self.tableViewDataSource reloadCellWithDataCount:_randoms.count groupIndex:0 cellIndex:0] 195 | ``` 196 | 197 | ### 显示和隐藏 198 | 199 | ![image-20200928190127141](https://gitee.com/joser_zhang/upic/raw/master/uPic/image-20200928190127141.png) 200 | 201 | ```objc 202 | [self.tableViewDataSource clearData]; 203 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 204 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 205 | cell.anyClass = [UITableViewCell class]; 206 | cell.identifier = @"UITableViewCell"; 207 | cell.cellNumber = 10; 208 | [cell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 209 | cell.textLabel.text = [@(indexPath.row + 1) stringValue]; 210 | }]; 211 | [cell setHiddenBlock:^BOOL(NSIndexPath *indexPath) { 212 | return _hidden && indexPath.row >= 5 && indexPath.row <= 8; 213 | }]; 214 | }]; 215 | }]; 216 | [self.tableViewDataSource reloadTableViewData]; 217 | ``` 218 | 219 | #### 隐藏Cell 220 | 221 | ```objc 222 | [self.tableViewDataSource reloadAllHiddenCell] 223 | ``` 224 | 225 | ## 怎么安装 226 | 227 | ### Cocoapods 228 | 229 | ```ruby 230 | pod 'ZHTableViewGroup' 231 | ``` 232 | 233 | ### Carthage 234 | 235 | ```ruby 236 | github "josercc/ZHTableViewGroup" 237 | ``` 238 | 239 | ### Swift Package Manager 240 | 241 | ```swift 242 | .package(url: "https://github.com/josercc/ZHTableViewGroup.git", from: "3.0.0") 243 | ``` 244 | 245 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import ZHTableViewGroupTests 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += ZHTableViewGroupTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Tests/ZHTableViewGroupTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(ZHTableViewGroupTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Tests/ZHTableViewGroupTests/ZHTableViewGroupTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import ZHTableViewGroup 3 | 4 | final class ZHTableViewGroupTests: XCTestCase { 5 | func testExample() { 6 | // This is an example of a functional test case. 7 | // Use XCTAssert and related functions to verify your tests produce the correct 8 | // results. 9 | } 10 | 11 | static var allTests = [ 12 | ("testExample", testExample), 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 17722FBC2404A78200CEC436 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17722FBB2404A78200CEC436 /* AppDelegate.m */; }; 11 | 17722FBF2404A78200CEC436 /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17722FBE2404A78200CEC436 /* SceneDelegate.m */; }; 12 | 17722FC22404A78200CEC436 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17722FC12404A78200CEC436 /* ViewController.m */; }; 13 | 17722FC52404A78200CEC436 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17722FC32404A78200CEC436 /* Main.storyboard */; }; 14 | 17722FC72404A78400CEC436 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 17722FC62404A78400CEC436 /* Assets.xcassets */; }; 15 | 17722FCA2404A78400CEC436 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17722FC82404A78400CEC436 /* LaunchScreen.storyboard */; }; 16 | 17722FCD2404A78500CEC436 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 17722FCC2404A78500CEC436 /* main.m */; }; 17 | 178360BE240E34A800FEEC2E /* ZHTableViewGroupObjc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 178360B7240E34A800FEEC2E /* ZHTableViewGroupObjc.framework */; }; 18 | 178360BF240E34A800FEEC2E /* ZHTableViewGroupObjc.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 178360B7240E34A800FEEC2E /* ZHTableViewGroupObjc.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 19 | 178360DC240E34C100FEEC2E /* ZHCollectionViewBaseModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360C3240E34C000FEEC2E /* ZHCollectionViewBaseModel.h */; settings = {ATTRIBUTES = (Public, ); }; }; 20 | 178360DE240E34C100FEEC2E /* ZHCollectionViewBaseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360C5240E34C000FEEC2E /* ZHCollectionViewBaseModel.m */; }; 21 | 178360DF240E34C100FEEC2E /* ZHTableViewHeaderFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360C6240E34C100FEEC2E /* ZHTableViewHeaderFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | 178360E0240E34C100FEEC2E /* ZHCollectionViewGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360C7240E34C100FEEC2E /* ZHCollectionViewGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23 | 178360E1240E34C100FEEC2E /* ZHTableViewBaseModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360C8240E34C100FEEC2E /* ZHTableViewBaseModel.h */; settings = {ATTRIBUTES = (Public, ); }; }; 24 | 178360E2240E34C100FEEC2E /* ZHTableViewDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360C9240E34C100FEEC2E /* ZHTableViewDataSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25 | 178360E3240E34C100FEEC2E /* ZHCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360CA240E34C100FEEC2E /* ZHCollectionViewCell.m */; }; 26 | 178360E4240E34C100FEEC2E /* ZHTableViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360CB240E34C100FEEC2E /* ZHTableViewDataSource.m */; }; 27 | 178360E5240E34C100FEEC2E /* ZHAutoConfigurationTableViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360CC240E34C100FEEC2E /* ZHAutoConfigurationTableViewDelegate.m */; }; 28 | 178360E6240E34C100FEEC2E /* ZHCollectionViewHeaderFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360CD240E34C100FEEC2E /* ZHCollectionViewHeaderFooter.m */; }; 29 | 178360E7240E34C100FEEC2E /* ZHTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360CE240E34C100FEEC2E /* ZHTableViewCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; 30 | 178360E8240E34C100FEEC2E /* ZHTableViewGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360CF240E34C100FEEC2E /* ZHTableViewGroup.m */; }; 31 | 178360E9240E34C100FEEC2E /* ZHAutoConfigurationCollectionViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360D0240E34C100FEEC2E /* ZHAutoConfigurationCollectionViewDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 32 | 178360EA240E34C100FEEC2E /* ZHTableViewGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360D1240E34C100FEEC2E /* ZHTableViewGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; 33 | 178360EB240E34C100FEEC2E /* ZHTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360D2240E34C100FEEC2E /* ZHTableViewCell.m */; }; 34 | 178360EC240E34C100FEEC2E /* ZHAutoConfigurationTableViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360D3240E34C100FEEC2E /* ZHAutoConfigurationTableViewDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 35 | 178360ED240E34C100FEEC2E /* ZHAutoConfigurationCollectionViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360D4240E34C100FEEC2E /* ZHAutoConfigurationCollectionViewDelegate.m */; }; 36 | 178360EE240E34C100FEEC2E /* ZHCollectionViewGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360D5240E34C100FEEC2E /* ZHCollectionViewGroup.m */; }; 37 | 178360EF240E34C100FEEC2E /* ZHCollectionViewDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360D6240E34C100FEEC2E /* ZHCollectionViewDataSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; 38 | 178360F0240E34C100FEEC2E /* ZHCollectionViewHeaderFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360D7240E34C100FEEC2E /* ZHCollectionViewHeaderFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 39 | 178360F1240E34C100FEEC2E /* ZHTableViewHeaderFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360D8240E34C100FEEC2E /* ZHTableViewHeaderFooter.m */; }; 40 | 178360F2240E34C100FEEC2E /* ZHCollectionViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360D9240E34C100FEEC2E /* ZHCollectionViewDataSource.m */; }; 41 | 178360F3240E34C100FEEC2E /* ZHTableViewBaseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 178360DA240E34C100FEEC2E /* ZHTableViewBaseModel.m */; }; 42 | 178360F4240E34C100FEEC2E /* ZHCollectionViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 178360DB240E34C100FEEC2E /* ZHCollectionViewCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; 43 | 17C9D6502404CACF00D7B871 /* ReloadHeightViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C9D64A2404C3F500D7B871 /* ReloadHeightViewController.m */; }; 44 | 17C9D6592404F1F300D7B871 /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C9D6572404F1F300D7B871 /* TableViewController.m */; }; 45 | 17C9D65A2404F1F300D7B871 /* TableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17C9D6582404F1F300D7B871 /* TableViewController.xib */; }; 46 | 17C9D65D2404FF0900D7B871 /* SetHeightViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C9D65C2404FF0900D7B871 /* SetHeightViewController.m */; }; 47 | 17C9D660240514F900D7B871 /* ReloadCellViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C9D65F240514F900D7B871 /* ReloadCellViewController.m */; }; 48 | 17C9D6632405198D00D7B871 /* ReloadCellDataViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C9D6622405198D00D7B871 /* ReloadCellDataViewController.m */; }; 49 | 17C9D6662406252200D7B871 /* HiddenViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C9D6652406252200D7B871 /* HiddenViewController.m */; }; 50 | 17E7C23D240F558A0073409B /* ZHTableViewGroupObjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 17E7C23C240F558A0073409B /* ZHTableViewGroupObjc.h */; settings = {ATTRIBUTES = (Public, ); }; }; 51 | /* End PBXBuildFile section */ 52 | 53 | /* Begin PBXContainerItemProxy section */ 54 | 178360BC240E34A800FEEC2E /* PBXContainerItemProxy */ = { 55 | isa = PBXContainerItemProxy; 56 | containerPortal = 17722FAF2404A78200CEC436 /* Project object */; 57 | proxyType = 1; 58 | remoteGlobalIDString = 178360B6240E34A800FEEC2E; 59 | remoteInfo = ZHTableViewGroupObjc; 60 | }; 61 | /* End PBXContainerItemProxy section */ 62 | 63 | /* Begin PBXCopyFilesBuildPhase section */ 64 | 17722FE42404A7D300CEC436 /* Embed Frameworks */ = { 65 | isa = PBXCopyFilesBuildPhase; 66 | buildActionMask = 2147483647; 67 | dstPath = ""; 68 | dstSubfolderSpec = 10; 69 | files = ( 70 | 178360BF240E34A800FEEC2E /* ZHTableViewGroupObjc.framework in Embed Frameworks */, 71 | ); 72 | name = "Embed Frameworks"; 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | /* End PBXCopyFilesBuildPhase section */ 76 | 77 | /* Begin PBXFileReference section */ 78 | 17722FB72404A78200CEC436 /* ZHTableViewGroupExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ZHTableViewGroupExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 79 | 17722FBA2404A78200CEC436 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 80 | 17722FBB2404A78200CEC436 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 81 | 17722FBD2404A78200CEC436 /* SceneDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SceneDelegate.h; sourceTree = ""; }; 82 | 17722FBE2404A78200CEC436 /* SceneDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SceneDelegate.m; sourceTree = ""; }; 83 | 17722FC02404A78200CEC436 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 84 | 17722FC12404A78200CEC436 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 85 | 17722FC42404A78200CEC436 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 86 | 17722FC62404A78400CEC436 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 87 | 17722FC92404A78400CEC436 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 88 | 17722FCB2404A78400CEC436 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 89 | 17722FCC2404A78500CEC436 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 90 | 178360B7240E34A800FEEC2E /* ZHTableViewGroupObjc.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ZHTableViewGroupObjc.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 91 | 178360BA240E34A800FEEC2E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 92 | 178360C3240E34C000FEEC2E /* ZHCollectionViewBaseModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHCollectionViewBaseModel.h; sourceTree = ""; }; 93 | 178360C5240E34C000FEEC2E /* ZHCollectionViewBaseModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHCollectionViewBaseModel.m; sourceTree = ""; }; 94 | 178360C6240E34C100FEEC2E /* ZHTableViewHeaderFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHTableViewHeaderFooter.h; sourceTree = ""; }; 95 | 178360C7240E34C100FEEC2E /* ZHCollectionViewGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHCollectionViewGroup.h; sourceTree = ""; }; 96 | 178360C8240E34C100FEEC2E /* ZHTableViewBaseModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHTableViewBaseModel.h; sourceTree = ""; }; 97 | 178360C9240E34C100FEEC2E /* ZHTableViewDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHTableViewDataSource.h; sourceTree = ""; }; 98 | 178360CA240E34C100FEEC2E /* ZHCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHCollectionViewCell.m; sourceTree = ""; }; 99 | 178360CB240E34C100FEEC2E /* ZHTableViewDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHTableViewDataSource.m; sourceTree = ""; }; 100 | 178360CC240E34C100FEEC2E /* ZHAutoConfigurationTableViewDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHAutoConfigurationTableViewDelegate.m; sourceTree = ""; }; 101 | 178360CD240E34C100FEEC2E /* ZHCollectionViewHeaderFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHCollectionViewHeaderFooter.m; sourceTree = ""; }; 102 | 178360CE240E34C100FEEC2E /* ZHTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHTableViewCell.h; sourceTree = ""; }; 103 | 178360CF240E34C100FEEC2E /* ZHTableViewGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHTableViewGroup.m; sourceTree = ""; }; 104 | 178360D0240E34C100FEEC2E /* ZHAutoConfigurationCollectionViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHAutoConfigurationCollectionViewDelegate.h; sourceTree = ""; }; 105 | 178360D1240E34C100FEEC2E /* ZHTableViewGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHTableViewGroup.h; sourceTree = ""; }; 106 | 178360D2240E34C100FEEC2E /* ZHTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHTableViewCell.m; sourceTree = ""; }; 107 | 178360D3240E34C100FEEC2E /* ZHAutoConfigurationTableViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHAutoConfigurationTableViewDelegate.h; sourceTree = ""; }; 108 | 178360D4240E34C100FEEC2E /* ZHAutoConfigurationCollectionViewDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHAutoConfigurationCollectionViewDelegate.m; sourceTree = ""; }; 109 | 178360D5240E34C100FEEC2E /* ZHCollectionViewGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHCollectionViewGroup.m; sourceTree = ""; }; 110 | 178360D6240E34C100FEEC2E /* ZHCollectionViewDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHCollectionViewDataSource.h; sourceTree = ""; }; 111 | 178360D7240E34C100FEEC2E /* ZHCollectionViewHeaderFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHCollectionViewHeaderFooter.h; sourceTree = ""; }; 112 | 178360D8240E34C100FEEC2E /* ZHTableViewHeaderFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHTableViewHeaderFooter.m; sourceTree = ""; }; 113 | 178360D9240E34C100FEEC2E /* ZHCollectionViewDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHCollectionViewDataSource.m; sourceTree = ""; }; 114 | 178360DA240E34C100FEEC2E /* ZHTableViewBaseModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZHTableViewBaseModel.m; sourceTree = ""; }; 115 | 178360DB240E34C100FEEC2E /* ZHCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHCollectionViewCell.h; sourceTree = ""; }; 116 | 17C9D6492404C3F500D7B871 /* ReloadHeightViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReloadHeightViewController.h; sourceTree = ""; }; 117 | 17C9D64A2404C3F500D7B871 /* ReloadHeightViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReloadHeightViewController.m; sourceTree = ""; }; 118 | 17C9D6562404F1F300D7B871 /* TableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TableViewController.h; sourceTree = ""; }; 119 | 17C9D6572404F1F300D7B871 /* TableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TableViewController.m; sourceTree = ""; }; 120 | 17C9D6582404F1F300D7B871 /* TableViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TableViewController.xib; sourceTree = ""; }; 121 | 17C9D65B2404FF0900D7B871 /* SetHeightViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SetHeightViewController.h; sourceTree = ""; }; 122 | 17C9D65C2404FF0900D7B871 /* SetHeightViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SetHeightViewController.m; sourceTree = ""; }; 123 | 17C9D65E240514F900D7B871 /* ReloadCellViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReloadCellViewController.h; sourceTree = ""; }; 124 | 17C9D65F240514F900D7B871 /* ReloadCellViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReloadCellViewController.m; sourceTree = ""; }; 125 | 17C9D6612405198D00D7B871 /* ReloadCellDataViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReloadCellDataViewController.h; sourceTree = ""; }; 126 | 17C9D6622405198D00D7B871 /* ReloadCellDataViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReloadCellDataViewController.m; sourceTree = ""; }; 127 | 17C9D6642406252200D7B871 /* HiddenViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HiddenViewController.h; sourceTree = ""; }; 128 | 17C9D6652406252200D7B871 /* HiddenViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HiddenViewController.m; sourceTree = ""; }; 129 | 17E7C23C240F558A0073409B /* ZHTableViewGroupObjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZHTableViewGroupObjc.h; sourceTree = ""; }; 130 | /* End PBXFileReference section */ 131 | 132 | /* Begin PBXFrameworksBuildPhase section */ 133 | 17722FB42404A78200CEC436 /* Frameworks */ = { 134 | isa = PBXFrameworksBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | 178360BE240E34A800FEEC2E /* ZHTableViewGroupObjc.framework in Frameworks */, 138 | ); 139 | runOnlyForDeploymentPostprocessing = 0; 140 | }; 141 | 178360B4240E34A800FEEC2E /* Frameworks */ = { 142 | isa = PBXFrameworksBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | ); 146 | runOnlyForDeploymentPostprocessing = 0; 147 | }; 148 | /* End PBXFrameworksBuildPhase section */ 149 | 150 | /* Begin PBXGroup section */ 151 | 17722FAE2404A78200CEC436 = { 152 | isa = PBXGroup; 153 | children = ( 154 | 17722FB92404A78200CEC436 /* ZHTableViewGroupExample */, 155 | 178360B8240E34A800FEEC2E /* ZHTableViewGroupObjc */, 156 | 17722FB82404A78200CEC436 /* Products */, 157 | ); 158 | sourceTree = ""; 159 | }; 160 | 17722FB82404A78200CEC436 /* Products */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 17722FB72404A78200CEC436 /* ZHTableViewGroupExample.app */, 164 | 178360B7240E34A800FEEC2E /* ZHTableViewGroupObjc.framework */, 165 | ); 166 | name = Products; 167 | sourceTree = ""; 168 | }; 169 | 17722FB92404A78200CEC436 /* ZHTableViewGroupExample */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 17722FBA2404A78200CEC436 /* AppDelegate.h */, 173 | 17722FBB2404A78200CEC436 /* AppDelegate.m */, 174 | 17722FBD2404A78200CEC436 /* SceneDelegate.h */, 175 | 17722FBE2404A78200CEC436 /* SceneDelegate.m */, 176 | 17722FC02404A78200CEC436 /* ViewController.h */, 177 | 17722FC12404A78200CEC436 /* ViewController.m */, 178 | 17C9D6492404C3F500D7B871 /* ReloadHeightViewController.h */, 179 | 17C9D64A2404C3F500D7B871 /* ReloadHeightViewController.m */, 180 | 17C9D65B2404FF0900D7B871 /* SetHeightViewController.h */, 181 | 17C9D65C2404FF0900D7B871 /* SetHeightViewController.m */, 182 | 17C9D65E240514F900D7B871 /* ReloadCellViewController.h */, 183 | 17C9D65F240514F900D7B871 /* ReloadCellViewController.m */, 184 | 17C9D6612405198D00D7B871 /* ReloadCellDataViewController.h */, 185 | 17C9D6622405198D00D7B871 /* ReloadCellDataViewController.m */, 186 | 17C9D6642406252200D7B871 /* HiddenViewController.h */, 187 | 17C9D6652406252200D7B871 /* HiddenViewController.m */, 188 | 17C9D6562404F1F300D7B871 /* TableViewController.h */, 189 | 17C9D6572404F1F300D7B871 /* TableViewController.m */, 190 | 17C9D6582404F1F300D7B871 /* TableViewController.xib */, 191 | 17722FC32404A78200CEC436 /* Main.storyboard */, 192 | 17722FC62404A78400CEC436 /* Assets.xcassets */, 193 | 17722FC82404A78400CEC436 /* LaunchScreen.storyboard */, 194 | 17722FCB2404A78400CEC436 /* Info.plist */, 195 | 17722FCC2404A78500CEC436 /* main.m */, 196 | ); 197 | path = ZHTableViewGroupExample; 198 | sourceTree = ""; 199 | }; 200 | 178360B8240E34A800FEEC2E /* ZHTableViewGroupObjc */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 178360D0240E34C100FEEC2E /* ZHAutoConfigurationCollectionViewDelegate.h */, 204 | 17E7C23C240F558A0073409B /* ZHTableViewGroupObjc.h */, 205 | 178360D4240E34C100FEEC2E /* ZHAutoConfigurationCollectionViewDelegate.m */, 206 | 178360D3240E34C100FEEC2E /* ZHAutoConfigurationTableViewDelegate.h */, 207 | 178360CC240E34C100FEEC2E /* ZHAutoConfigurationTableViewDelegate.m */, 208 | 178360C3240E34C000FEEC2E /* ZHCollectionViewBaseModel.h */, 209 | 178360C5240E34C000FEEC2E /* ZHCollectionViewBaseModel.m */, 210 | 178360DB240E34C100FEEC2E /* ZHCollectionViewCell.h */, 211 | 178360CA240E34C100FEEC2E /* ZHCollectionViewCell.m */, 212 | 178360D6240E34C100FEEC2E /* ZHCollectionViewDataSource.h */, 213 | 178360D9240E34C100FEEC2E /* ZHCollectionViewDataSource.m */, 214 | 178360C7240E34C100FEEC2E /* ZHCollectionViewGroup.h */, 215 | 178360D5240E34C100FEEC2E /* ZHCollectionViewGroup.m */, 216 | 178360D7240E34C100FEEC2E /* ZHCollectionViewHeaderFooter.h */, 217 | 178360CD240E34C100FEEC2E /* ZHCollectionViewHeaderFooter.m */, 218 | 178360C8240E34C100FEEC2E /* ZHTableViewBaseModel.h */, 219 | 178360DA240E34C100FEEC2E /* ZHTableViewBaseModel.m */, 220 | 178360CE240E34C100FEEC2E /* ZHTableViewCell.h */, 221 | 178360D2240E34C100FEEC2E /* ZHTableViewCell.m */, 222 | 178360C9240E34C100FEEC2E /* ZHTableViewDataSource.h */, 223 | 178360CB240E34C100FEEC2E /* ZHTableViewDataSource.m */, 224 | 178360D1240E34C100FEEC2E /* ZHTableViewGroup.h */, 225 | 178360CF240E34C100FEEC2E /* ZHTableViewGroup.m */, 226 | 178360C6240E34C100FEEC2E /* ZHTableViewHeaderFooter.h */, 227 | 178360D8240E34C100FEEC2E /* ZHTableViewHeaderFooter.m */, 228 | 178360BA240E34A800FEEC2E /* Info.plist */, 229 | ); 230 | path = ZHTableViewGroupObjc; 231 | sourceTree = ""; 232 | }; 233 | /* End PBXGroup section */ 234 | 235 | /* Begin PBXHeadersBuildPhase section */ 236 | 178360B2240E34A800FEEC2E /* Headers */ = { 237 | isa = PBXHeadersBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | 178360E1240E34C100FEEC2E /* ZHTableViewBaseModel.h in Headers */, 241 | 178360E2240E34C100FEEC2E /* ZHTableViewDataSource.h in Headers */, 242 | 178360DC240E34C100FEEC2E /* ZHCollectionViewBaseModel.h in Headers */, 243 | 178360F4240E34C100FEEC2E /* ZHCollectionViewCell.h in Headers */, 244 | 178360EF240E34C100FEEC2E /* ZHCollectionViewDataSource.h in Headers */, 245 | 178360E7240E34C100FEEC2E /* ZHTableViewCell.h in Headers */, 246 | 178360DF240E34C100FEEC2E /* ZHTableViewHeaderFooter.h in Headers */, 247 | 178360E9240E34C100FEEC2E /* ZHAutoConfigurationCollectionViewDelegate.h in Headers */, 248 | 17E7C23D240F558A0073409B /* ZHTableViewGroupObjc.h in Headers */, 249 | 178360E0240E34C100FEEC2E /* ZHCollectionViewGroup.h in Headers */, 250 | 178360F0240E34C100FEEC2E /* ZHCollectionViewHeaderFooter.h in Headers */, 251 | 178360EA240E34C100FEEC2E /* ZHTableViewGroup.h in Headers */, 252 | 178360EC240E34C100FEEC2E /* ZHAutoConfigurationTableViewDelegate.h in Headers */, 253 | ); 254 | runOnlyForDeploymentPostprocessing = 0; 255 | }; 256 | /* End PBXHeadersBuildPhase section */ 257 | 258 | /* Begin PBXNativeTarget section */ 259 | 17722FB62404A78200CEC436 /* ZHTableViewGroupExample */ = { 260 | isa = PBXNativeTarget; 261 | buildConfigurationList = 17722FD02404A78500CEC436 /* Build configuration list for PBXNativeTarget "ZHTableViewGroupExample" */; 262 | buildPhases = ( 263 | 17722FB32404A78200CEC436 /* Sources */, 264 | 17722FB42404A78200CEC436 /* Frameworks */, 265 | 17722FB52404A78200CEC436 /* Resources */, 266 | 17722FE42404A7D300CEC436 /* Embed Frameworks */, 267 | ); 268 | buildRules = ( 269 | ); 270 | dependencies = ( 271 | 178360BD240E34A800FEEC2E /* PBXTargetDependency */, 272 | ); 273 | name = ZHTableViewGroupExample; 274 | productName = ZHTableViewGroupExample; 275 | productReference = 17722FB72404A78200CEC436 /* ZHTableViewGroupExample.app */; 276 | productType = "com.apple.product-type.application"; 277 | }; 278 | 178360B6240E34A800FEEC2E /* ZHTableViewGroupObjc */ = { 279 | isa = PBXNativeTarget; 280 | buildConfigurationList = 178360C0240E34A800FEEC2E /* Build configuration list for PBXNativeTarget "ZHTableViewGroupObjc" */; 281 | buildPhases = ( 282 | 178360B2240E34A800FEEC2E /* Headers */, 283 | 178360B3240E34A800FEEC2E /* Sources */, 284 | 178360B4240E34A800FEEC2E /* Frameworks */, 285 | 178360B5240E34A800FEEC2E /* Resources */, 286 | ); 287 | buildRules = ( 288 | ); 289 | dependencies = ( 290 | ); 291 | name = ZHTableViewGroupObjc; 292 | productName = ZHTableViewGroupObjc; 293 | productReference = 178360B7240E34A800FEEC2E /* ZHTableViewGroupObjc.framework */; 294 | productType = "com.apple.product-type.framework"; 295 | }; 296 | /* End PBXNativeTarget section */ 297 | 298 | /* Begin PBXProject section */ 299 | 17722FAF2404A78200CEC436 /* Project object */ = { 300 | isa = PBXProject; 301 | attributes = { 302 | LastUpgradeCheck = 1110; 303 | ORGANIZATIONNAME = josercc; 304 | TargetAttributes = { 305 | 17722FB62404A78200CEC436 = { 306 | CreatedOnToolsVersion = 11.1; 307 | }; 308 | 178360B6240E34A800FEEC2E = { 309 | CreatedOnToolsVersion = 11.1; 310 | }; 311 | }; 312 | }; 313 | buildConfigurationList = 17722FB22404A78200CEC436 /* Build configuration list for PBXProject "ZHTableViewGroupExample" */; 314 | compatibilityVersion = "Xcode 9.3"; 315 | developmentRegion = en; 316 | hasScannedForEncodings = 0; 317 | knownRegions = ( 318 | en, 319 | Base, 320 | ); 321 | mainGroup = 17722FAE2404A78200CEC436; 322 | productRefGroup = 17722FB82404A78200CEC436 /* Products */; 323 | projectDirPath = ""; 324 | projectRoot = ""; 325 | targets = ( 326 | 17722FB62404A78200CEC436 /* ZHTableViewGroupExample */, 327 | 178360B6240E34A800FEEC2E /* ZHTableViewGroupObjc */, 328 | ); 329 | }; 330 | /* End PBXProject section */ 331 | 332 | /* Begin PBXResourcesBuildPhase section */ 333 | 17722FB52404A78200CEC436 /* Resources */ = { 334 | isa = PBXResourcesBuildPhase; 335 | buildActionMask = 2147483647; 336 | files = ( 337 | 17722FCA2404A78400CEC436 /* LaunchScreen.storyboard in Resources */, 338 | 17722FC72404A78400CEC436 /* Assets.xcassets in Resources */, 339 | 17C9D65A2404F1F300D7B871 /* TableViewController.xib in Resources */, 340 | 17722FC52404A78200CEC436 /* Main.storyboard in Resources */, 341 | ); 342 | runOnlyForDeploymentPostprocessing = 0; 343 | }; 344 | 178360B5240E34A800FEEC2E /* Resources */ = { 345 | isa = PBXResourcesBuildPhase; 346 | buildActionMask = 2147483647; 347 | files = ( 348 | ); 349 | runOnlyForDeploymentPostprocessing = 0; 350 | }; 351 | /* End PBXResourcesBuildPhase section */ 352 | 353 | /* Begin PBXSourcesBuildPhase section */ 354 | 17722FB32404A78200CEC436 /* Sources */ = { 355 | isa = PBXSourcesBuildPhase; 356 | buildActionMask = 2147483647; 357 | files = ( 358 | 17722FC22404A78200CEC436 /* ViewController.m in Sources */, 359 | 17C9D6592404F1F300D7B871 /* TableViewController.m in Sources */, 360 | 17C9D6662406252200D7B871 /* HiddenViewController.m in Sources */, 361 | 17C9D65D2404FF0900D7B871 /* SetHeightViewController.m in Sources */, 362 | 17C9D6632405198D00D7B871 /* ReloadCellDataViewController.m in Sources */, 363 | 17C9D660240514F900D7B871 /* ReloadCellViewController.m in Sources */, 364 | 17722FBC2404A78200CEC436 /* AppDelegate.m in Sources */, 365 | 17722FCD2404A78500CEC436 /* main.m in Sources */, 366 | 17C9D6502404CACF00D7B871 /* ReloadHeightViewController.m in Sources */, 367 | 17722FBF2404A78200CEC436 /* SceneDelegate.m in Sources */, 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | 178360B3240E34A800FEEC2E /* Sources */ = { 372 | isa = PBXSourcesBuildPhase; 373 | buildActionMask = 2147483647; 374 | files = ( 375 | 178360E3240E34C100FEEC2E /* ZHCollectionViewCell.m in Sources */, 376 | 178360F1240E34C100FEEC2E /* ZHTableViewHeaderFooter.m in Sources */, 377 | 178360F3240E34C100FEEC2E /* ZHTableViewBaseModel.m in Sources */, 378 | 178360F2240E34C100FEEC2E /* ZHCollectionViewDataSource.m in Sources */, 379 | 178360EB240E34C100FEEC2E /* ZHTableViewCell.m in Sources */, 380 | 178360E6240E34C100FEEC2E /* ZHCollectionViewHeaderFooter.m in Sources */, 381 | 178360ED240E34C100FEEC2E /* ZHAutoConfigurationCollectionViewDelegate.m in Sources */, 382 | 178360E4240E34C100FEEC2E /* ZHTableViewDataSource.m in Sources */, 383 | 178360E8240E34C100FEEC2E /* ZHTableViewGroup.m in Sources */, 384 | 178360E5240E34C100FEEC2E /* ZHAutoConfigurationTableViewDelegate.m in Sources */, 385 | 178360EE240E34C100FEEC2E /* ZHCollectionViewGroup.m in Sources */, 386 | 178360DE240E34C100FEEC2E /* ZHCollectionViewBaseModel.m in Sources */, 387 | ); 388 | runOnlyForDeploymentPostprocessing = 0; 389 | }; 390 | /* End PBXSourcesBuildPhase section */ 391 | 392 | /* Begin PBXTargetDependency section */ 393 | 178360BD240E34A800FEEC2E /* PBXTargetDependency */ = { 394 | isa = PBXTargetDependency; 395 | target = 178360B6240E34A800FEEC2E /* ZHTableViewGroupObjc */; 396 | targetProxy = 178360BC240E34A800FEEC2E /* PBXContainerItemProxy */; 397 | }; 398 | /* End PBXTargetDependency section */ 399 | 400 | /* Begin PBXVariantGroup section */ 401 | 17722FC32404A78200CEC436 /* Main.storyboard */ = { 402 | isa = PBXVariantGroup; 403 | children = ( 404 | 17722FC42404A78200CEC436 /* Base */, 405 | ); 406 | name = Main.storyboard; 407 | sourceTree = ""; 408 | }; 409 | 17722FC82404A78400CEC436 /* LaunchScreen.storyboard */ = { 410 | isa = PBXVariantGroup; 411 | children = ( 412 | 17722FC92404A78400CEC436 /* Base */, 413 | ); 414 | name = LaunchScreen.storyboard; 415 | sourceTree = ""; 416 | }; 417 | /* End PBXVariantGroup section */ 418 | 419 | /* Begin XCBuildConfiguration section */ 420 | 17722FCE2404A78500CEC436 /* Debug */ = { 421 | isa = XCBuildConfiguration; 422 | buildSettings = { 423 | ALWAYS_SEARCH_USER_PATHS = NO; 424 | CLANG_ANALYZER_NONNULL = YES; 425 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 426 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 427 | CLANG_CXX_LIBRARY = "libc++"; 428 | CLANG_ENABLE_MODULES = YES; 429 | CLANG_ENABLE_OBJC_ARC = YES; 430 | CLANG_ENABLE_OBJC_WEAK = YES; 431 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 432 | CLANG_WARN_BOOL_CONVERSION = YES; 433 | CLANG_WARN_COMMA = YES; 434 | CLANG_WARN_CONSTANT_CONVERSION = YES; 435 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 436 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 437 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 438 | CLANG_WARN_EMPTY_BODY = YES; 439 | CLANG_WARN_ENUM_CONVERSION = YES; 440 | CLANG_WARN_INFINITE_RECURSION = YES; 441 | CLANG_WARN_INT_CONVERSION = YES; 442 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 443 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 444 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 445 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 446 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 447 | CLANG_WARN_STRICT_PROTOTYPES = YES; 448 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 449 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 450 | CLANG_WARN_UNREACHABLE_CODE = YES; 451 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 452 | COPY_PHASE_STRIP = NO; 453 | DEBUG_INFORMATION_FORMAT = dwarf; 454 | ENABLE_STRICT_OBJC_MSGSEND = YES; 455 | ENABLE_TESTABILITY = YES; 456 | GCC_C_LANGUAGE_STANDARD = gnu11; 457 | GCC_DYNAMIC_NO_PIC = NO; 458 | GCC_NO_COMMON_BLOCKS = YES; 459 | GCC_OPTIMIZATION_LEVEL = 0; 460 | GCC_PREPROCESSOR_DEFINITIONS = ( 461 | "DEBUG=1", 462 | "$(inherited)", 463 | ); 464 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 465 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 466 | GCC_WARN_UNDECLARED_SELECTOR = YES; 467 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 468 | GCC_WARN_UNUSED_FUNCTION = YES; 469 | GCC_WARN_UNUSED_VARIABLE = YES; 470 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 471 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 472 | MTL_FAST_MATH = YES; 473 | ONLY_ACTIVE_ARCH = YES; 474 | SDKROOT = iphoneos; 475 | }; 476 | name = Debug; 477 | }; 478 | 17722FCF2404A78500CEC436 /* Release */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | ALWAYS_SEARCH_USER_PATHS = NO; 482 | CLANG_ANALYZER_NONNULL = YES; 483 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 484 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 485 | CLANG_CXX_LIBRARY = "libc++"; 486 | CLANG_ENABLE_MODULES = YES; 487 | CLANG_ENABLE_OBJC_ARC = YES; 488 | CLANG_ENABLE_OBJC_WEAK = YES; 489 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 490 | CLANG_WARN_BOOL_CONVERSION = YES; 491 | CLANG_WARN_COMMA = YES; 492 | CLANG_WARN_CONSTANT_CONVERSION = YES; 493 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 494 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 495 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 496 | CLANG_WARN_EMPTY_BODY = YES; 497 | CLANG_WARN_ENUM_CONVERSION = YES; 498 | CLANG_WARN_INFINITE_RECURSION = YES; 499 | CLANG_WARN_INT_CONVERSION = YES; 500 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 501 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 502 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 503 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 504 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 505 | CLANG_WARN_STRICT_PROTOTYPES = YES; 506 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 507 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 508 | CLANG_WARN_UNREACHABLE_CODE = YES; 509 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 510 | COPY_PHASE_STRIP = NO; 511 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 512 | ENABLE_NS_ASSERTIONS = NO; 513 | ENABLE_STRICT_OBJC_MSGSEND = YES; 514 | GCC_C_LANGUAGE_STANDARD = gnu11; 515 | GCC_NO_COMMON_BLOCKS = YES; 516 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 517 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 518 | GCC_WARN_UNDECLARED_SELECTOR = YES; 519 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 520 | GCC_WARN_UNUSED_FUNCTION = YES; 521 | GCC_WARN_UNUSED_VARIABLE = YES; 522 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 523 | MTL_ENABLE_DEBUG_INFO = NO; 524 | MTL_FAST_MATH = YES; 525 | SDKROOT = iphoneos; 526 | VALIDATE_PRODUCT = YES; 527 | }; 528 | name = Release; 529 | }; 530 | 17722FD12404A78500CEC436 /* Debug */ = { 531 | isa = XCBuildConfiguration; 532 | buildSettings = { 533 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 534 | CODE_SIGN_STYLE = Automatic; 535 | DEVELOPMENT_TEAM = 9RWES6K38C; 536 | INFOPLIST_FILE = ZHTableViewGroupExample/Info.plist; 537 | LD_RUNPATH_SEARCH_PATHS = ( 538 | "$(inherited)", 539 | "@executable_path/Frameworks", 540 | ); 541 | PRODUCT_BUNDLE_IDENTIFIER = com.globalegrow.ZHTableViewGroupExample; 542 | PRODUCT_NAME = "$(TARGET_NAME)"; 543 | TARGETED_DEVICE_FAMILY = "1,2"; 544 | }; 545 | name = Debug; 546 | }; 547 | 17722FD22404A78500CEC436 /* Release */ = { 548 | isa = XCBuildConfiguration; 549 | buildSettings = { 550 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 551 | CODE_SIGN_STYLE = Automatic; 552 | DEVELOPMENT_TEAM = 9RWES6K38C; 553 | INFOPLIST_FILE = ZHTableViewGroupExample/Info.plist; 554 | LD_RUNPATH_SEARCH_PATHS = ( 555 | "$(inherited)", 556 | "@executable_path/Frameworks", 557 | ); 558 | PRODUCT_BUNDLE_IDENTIFIER = com.globalegrow.ZHTableViewGroupExample; 559 | PRODUCT_NAME = "$(TARGET_NAME)"; 560 | TARGETED_DEVICE_FAMILY = "1,2"; 561 | }; 562 | name = Release; 563 | }; 564 | 178360C1240E34A800FEEC2E /* Debug */ = { 565 | isa = XCBuildConfiguration; 566 | buildSettings = { 567 | CODE_SIGN_STYLE = Automatic; 568 | CURRENT_PROJECT_VERSION = 1; 569 | DEFINES_MODULE = YES; 570 | DEVELOPMENT_TEAM = 9RWES6K38C; 571 | DYLIB_COMPATIBILITY_VERSION = 1; 572 | DYLIB_CURRENT_VERSION = 1; 573 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 574 | INFOPLIST_FILE = ZHTableViewGroupObjc/Info.plist; 575 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 576 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 577 | LD_RUNPATH_SEARCH_PATHS = ( 578 | "$(inherited)", 579 | "@executable_path/Frameworks", 580 | "@loader_path/Frameworks", 581 | ); 582 | PRODUCT_BUNDLE_IDENTIFIER = com.globalegrow.ZHTableViewGroupObjc; 583 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 584 | SKIP_INSTALL = YES; 585 | TARGETED_DEVICE_FAMILY = "1,2"; 586 | VERSIONING_SYSTEM = "apple-generic"; 587 | VERSION_INFO_PREFIX = ""; 588 | }; 589 | name = Debug; 590 | }; 591 | 178360C2240E34A800FEEC2E /* Release */ = { 592 | isa = XCBuildConfiguration; 593 | buildSettings = { 594 | CODE_SIGN_STYLE = Automatic; 595 | CURRENT_PROJECT_VERSION = 1; 596 | DEFINES_MODULE = YES; 597 | DEVELOPMENT_TEAM = 9RWES6K38C; 598 | DYLIB_COMPATIBILITY_VERSION = 1; 599 | DYLIB_CURRENT_VERSION = 1; 600 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 601 | INFOPLIST_FILE = ZHTableViewGroupObjc/Info.plist; 602 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 603 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 604 | LD_RUNPATH_SEARCH_PATHS = ( 605 | "$(inherited)", 606 | "@executable_path/Frameworks", 607 | "@loader_path/Frameworks", 608 | ); 609 | PRODUCT_BUNDLE_IDENTIFIER = com.globalegrow.ZHTableViewGroupObjc; 610 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 611 | SKIP_INSTALL = YES; 612 | TARGETED_DEVICE_FAMILY = "1,2"; 613 | VERSIONING_SYSTEM = "apple-generic"; 614 | VERSION_INFO_PREFIX = ""; 615 | }; 616 | name = Release; 617 | }; 618 | /* End XCBuildConfiguration section */ 619 | 620 | /* Begin XCConfigurationList section */ 621 | 17722FB22404A78200CEC436 /* Build configuration list for PBXProject "ZHTableViewGroupExample" */ = { 622 | isa = XCConfigurationList; 623 | buildConfigurations = ( 624 | 17722FCE2404A78500CEC436 /* Debug */, 625 | 17722FCF2404A78500CEC436 /* Release */, 626 | ); 627 | defaultConfigurationIsVisible = 0; 628 | defaultConfigurationName = Release; 629 | }; 630 | 17722FD02404A78500CEC436 /* Build configuration list for PBXNativeTarget "ZHTableViewGroupExample" */ = { 631 | isa = XCConfigurationList; 632 | buildConfigurations = ( 633 | 17722FD12404A78500CEC436 /* Debug */, 634 | 17722FD22404A78500CEC436 /* Release */, 635 | ); 636 | defaultConfigurationIsVisible = 0; 637 | defaultConfigurationName = Release; 638 | }; 639 | 178360C0240E34A800FEEC2E /* Build configuration list for PBXNativeTarget "ZHTableViewGroupObjc" */ = { 640 | isa = XCConfigurationList; 641 | buildConfigurations = ( 642 | 178360C1240E34A800FEEC2E /* Debug */, 643 | 178360C2240E34A800FEEC2E /* Release */, 644 | ); 645 | defaultConfigurationIsVisible = 0; 646 | defaultConfigurationName = Release; 647 | }; 648 | /* End XCConfigurationList section */ 649 | }; 650 | rootObject = 17722FAF2404A78200CEC436 /* Project object */; 651 | } 652 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample.xcodeproj/xcshareddata/xcschemes/ZHTableViewGroupObjc.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | #pragma mark - UISceneSession lifecycle 25 | 26 | 27 | - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { 28 | // Called when a new scene session is being created. 29 | // Use this method to select a configuration to create the new scene with. 30 | return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role]; 31 | } 32 | 33 | 34 | - (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { 35 | // Called when the user discards a scene session. 36 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 37 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 38 | } 39 | 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/HiddenViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // HiddenViewController.h 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/26. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "TableViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface HiddenViewController : TableViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/HiddenViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // HiddenViewController.m 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/26. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "HiddenViewController.h" 10 | 11 | @interface HiddenViewController () 12 | 13 | @end 14 | 15 | @implementation HiddenViewController { 16 | BOOL _hidden; 17 | } 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | [self.tableViewDataSource clearData]; 22 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 23 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 24 | cell.anyClass = [UITableViewCell class]; 25 | cell.identifier = @"UITableViewCell"; 26 | cell.cellNumber = 10; 27 | [cell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 28 | cell.textLabel.text = [@(indexPath.row + 1) stringValue]; 29 | }]; 30 | [cell setHiddenBlock:^BOOL(NSIndexPath *indexPath) { 31 | return _hidden && indexPath.row >= 5 && indexPath.row <= 8; 32 | }]; 33 | }]; 34 | }]; 35 | [self.tableViewDataSource reloadTableViewData]; 36 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"刷新" style:UIBarButtonItemStylePlain target:self action:@selector(refresh)]; 37 | } 38 | 39 | - (void)refresh { 40 | _hidden = !_hidden; 41 | [self.tableViewDataSource reloadAllHiddenCell]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIMainStoryboardFile 45 | Main 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UISupportedInterfaceOrientations 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationLandscapeLeft 54 | UIInterfaceOrientationLandscapeRight 55 | 56 | UISupportedInterfaceOrientations~ipad 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationPortraitUpsideDown 60 | UIInterfaceOrientationLandscapeLeft 61 | UIInterfaceOrientationLandscapeRight 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/ReloadCellDataViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ReloadCellDataViewController.h 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "TableViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ReloadCellDataViewController : TableViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/ReloadCellDataViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ReloadCellDataViewController.m 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "ReloadCellDataViewController.h" 10 | 11 | @interface ReloadCellDataViewController () 12 | 13 | @end 14 | 15 | @implementation ReloadCellDataViewController { 16 | NSUInteger _index; 17 | NSMutableArray *_randoms; 18 | } 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | _randoms = [NSMutableArray arrayWithArray:@[@"random"]]; 23 | [self.tableViewDataSource clearData]; 24 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 25 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 26 | cell.anyClass = [UITableViewCell class]; 27 | cell.identifier = @"UITableViewCell"; 28 | cell.cellNumber = _randoms.count; 29 | [cell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 30 | cell.textLabel.text = _randoms[indexPath.row]; 31 | }]; 32 | }]; 33 | }]; 34 | [self.tableViewDataSource reloadTableViewData]; 35 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"刷新" style:UIBarButtonItemStylePlain target:self action:@selector(refresh)]; 36 | } 37 | 38 | - (void)refresh { 39 | _index = MIN(3, _index); 40 | NSUInteger randomCount = random() % 9 + 1; 41 | [_randoms removeAllObjects]; 42 | for (NSUInteger i = 0; i < randomCount; i++) { 43 | [_randoms addObject:[NSString stringWithFormat:@"random:%@",@(i)]]; 44 | } 45 | if (_index == 0) { 46 | [self.tableViewDataSource reloadCellWithDataCount:_randoms.count identifier:@"UITableViewCell"]; 47 | } else if (_index == 1) { 48 | [self.tableViewDataSource reloadCellWithDataCount:_randoms.count className:[UITableViewCell class]]; 49 | } else if (_index == 2) { 50 | [self.tableViewDataSource reloadCellWithDataCount:_randoms.count tableViewCell:self.tableViewDataSource.groups[0].cells[0]]; 51 | } else if (_index == 3) { 52 | [self.tableViewDataSource reloadCellWithDataCount:_randoms.count groupIndex:0 cellIndex:0]; 53 | } 54 | _index += 1; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/ReloadCellViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ReloadCellViewController.h 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "TableViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ReloadCellViewController : TableViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/ReloadCellViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ReloadCellViewController.m 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "ReloadCellViewController.h" 10 | 11 | @interface ReloadCellViewController () 12 | 13 | @end 14 | 15 | @implementation ReloadCellViewController { 16 | NSUInteger _index; 17 | } 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | [self.tableViewDataSource clearData]; 23 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 24 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 25 | cell.anyClass = [UITableViewCell class]; 26 | cell.identifier = @"UITableViewCell"; 27 | [cell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 28 | cell.textLabel.text = [@(random() % 99 + 1) stringValue]; 29 | }]; 30 | }]; 31 | }]; 32 | [self.tableViewDataSource reloadTableViewData]; 33 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"刷新" style:UIBarButtonItemStylePlain target:self action:@selector(refresh)]; 34 | } 35 | 36 | - (void)refresh { 37 | _index = MIN(3, _index); 38 | if (_index == 0) { 39 | [self.tableViewDataSource reloadCellWithIdentifier:@"UITableViewCell"]; 40 | } else if (_index == 1) { 41 | [self.tableViewDataSource reloadCellWithClassName:[UITableViewCell class]]; 42 | } else if (_index == 2) { 43 | [self.tableViewDataSource reloadCellWithTableViewCell:self.tableViewDataSource.groups[0].cells[0]]; 44 | } else if (_index == 3) { 45 | [self.tableViewDataSource reloadCellWithGroupIndex:0 cellIndex:0]; 46 | } 47 | _index += 1; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/ReloadHeightViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ReloadHeightViewController.h 3 | // ZHTableViewGroupObjc 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TableViewController.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | @class ReloadHeightCell1, ReloadHeightCell2; 14 | 15 | @interface ReloadHeightViewController : TableViewController 16 | 17 | @end 18 | 19 | @interface ReloadHeightCell1 : UITableViewCell 20 | 21 | @end 22 | 23 | @interface ReloadHeightCell2 : UITableViewCell 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/ReloadHeightViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ReloadHeightViewController.m 3 | // ZHTableViewGroupObjc 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "ReloadHeightViewController.h" 10 | #import 11 | #import "SetHeightViewController.h" 12 | 13 | @interface ReloadHeightViewController () 14 | 15 | 16 | @end 17 | 18 | @implementation ReloadHeightViewController { 19 | __block ZHTableViewCell *_weakCell; 20 | } 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | [self.tableViewDataSource clearData]; 25 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 26 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 27 | self->_weakCell = cell; 28 | cell.anyClass = [ReloadHeightCell1 class]; 29 | cell.identifier = @"ReloadHeightCell1"; 30 | [cell setConfigCompletionHandle:^(ReloadHeightCell1 *cell1, NSIndexPath *indexPath) { 31 | cell1.textLabel.text = @"ReloadHeightCell1"; 32 | }]; 33 | }]; 34 | }]; 35 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 36 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 37 | cell.anyClass = [ReloadHeightCell2 class]; 38 | cell.identifier = @"ReloadHeightCell2"; 39 | cell.cellNumber = 2; 40 | [cell setConfigCompletionHandle:^(ReloadHeightCell2 *cell1, NSIndexPath *indexPath) { 41 | cell1.textLabel.text = @"ReloadHeightCell2"; 42 | }]; 43 | }]; 44 | }]; 45 | [self.tableViewDataSource reloadTableViewData]; 46 | 47 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"刷新高度" 48 | style:UIBarButtonItemStylePlain 49 | target:self 50 | action:@selector(reloadHeight)]; 51 | } 52 | 53 | - (void)reloadHeight { 54 | SetHeightViewController *controller = [[SetHeightViewController alloc] initWithNibName:nil bundle:nil]; 55 | controller.updateTableViewDataSource = self.tableViewDataSource; 56 | [self presentViewController:controller animated:YES completion:nil]; 57 | } 58 | 59 | 60 | @end 61 | 62 | @implementation ReloadHeightCell1 63 | 64 | - (CGSize)sizeThatFits:(CGSize)size { 65 | return CGSizeMake(size.width, 85); 66 | } 67 | 68 | @end 69 | 70 | @implementation ReloadHeightCell2 71 | 72 | - (CGSize)sizeThatFits:(CGSize)size { 73 | return CGSizeMake(size.width, 105); 74 | } 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/SceneDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.h 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SceneDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow * window; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/SceneDelegate.m: -------------------------------------------------------------------------------- 1 | #import "SceneDelegate.h" 2 | 3 | @interface SceneDelegate () 4 | 5 | @end 6 | 7 | @implementation SceneDelegate 8 | 9 | 10 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { 11 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 12 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 13 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 14 | } 15 | 16 | 17 | - (void)sceneDidDisconnect:(UIScene *)scene { 18 | // Called as the scene is being released by the system. 19 | // This occurs shortly after the scene enters the background, or when its session is discarded. 20 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 21 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 22 | } 23 | 24 | 25 | - (void)sceneDidBecomeActive:(UIScene *)scene { 26 | // Called when the scene has moved from an inactive state to an active state. 27 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 28 | } 29 | 30 | 31 | - (void)sceneWillResignActive:(UIScene *)scene { 32 | // Called when the scene will move from an active state to an inactive state. 33 | // This may occur due to temporary interruptions (ex. an incoming phone call). 34 | } 35 | 36 | 37 | - (void)sceneWillEnterForeground:(UIScene *)scene { 38 | // Called as the scene transitions from the background to the foreground. 39 | // Use this method to undo the changes made on entering the background. 40 | } 41 | 42 | 43 | - (void)sceneDidEnterBackground:(UIScene *)scene { 44 | // Called as the scene transitions from the foreground to the background. 45 | // Use this method to save data, release shared resources, and store enough scene-specific state information 46 | // to restore the scene back to its current state. 47 | } 48 | 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/SetHeightViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SetHeightViewController.h 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "TableViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SetHeightViewController : TableViewController 14 | 15 | @property (nonatomic, weak) ZHTableViewDataSource *updateTableViewDataSource; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/SetHeightViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SetHeightViewController.m 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "SetHeightViewController.h" 10 | 11 | @interface SetHeightViewController () 12 | 13 | @end 14 | 15 | @implementation SetHeightViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | NSArray *titles = @[ 20 | @"identifier更新自动高度", 21 | @"identifier更新固定250高度", 22 | @"Class更新自动高度", 23 | @"Class更新固定260高度", 24 | @"指定ZHTableViewCell更新自动高度", 25 | @"指定ZHTableViewCell更新固定270高度", 26 | @"指定索引更新自动高度", 27 | @"指定索引更新固定280高度", 28 | ]; 29 | [self.tableViewDataSource clearData]; 30 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 31 | [group addCellWithCompletionHandle:^(ZHTableViewCell *cell) { 32 | cell.anyClass = [UITableViewCell class]; 33 | cell.identifier = @"UITableViewCell"; 34 | cell.cellNumber = titles.count; 35 | [cell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 36 | cell.textLabel.text = titles[indexPath.row]; 37 | }]; 38 | [cell setDidSelectRowCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 39 | if (indexPath.row == 0) { 40 | [self.updateTableViewDataSource reloadCellAutomaticHeightWithIdentifier:@"ReloadHeightCell1"]; 41 | } else if (indexPath.row == 1) { 42 | [self.updateTableViewDataSource reloadCellFixedHeight:250 identifier:@"ReloadHeightCell1"]; 43 | } else if (indexPath.row == 2) { 44 | [self.updateTableViewDataSource reloadCellAutomaticHeightWithClass:NSClassFromString(@"ReloadHeightCell1")]; 45 | } else if (indexPath.row == 3) { 46 | [self.updateTableViewDataSource reloadCellFixedHeight:260 className:NSClassFromString(@"ReloadHeightCell1")]; 47 | } else if (indexPath.row == 4) { 48 | [self.updateTableViewDataSource reloadCellAutomaticHeightWithTableViewCell:self.updateTableViewDataSource.groups[0].cells[0]]; 49 | } else if (indexPath.row == 5) { 50 | [self.updateTableViewDataSource reloadCellFixedHeight:270 tableViewCell:self.updateTableViewDataSource.groups[0].cells[0]]; 51 | } else if (indexPath.row == 6) { 52 | [self.updateTableViewDataSource reloadCellAutomicHeightWithGroupIndex:1 cellIndex:0]; 53 | } else if (indexPath.row == 7) { 54 | [self.updateTableViewDataSource reloadCellFixedHeight:280 groupIndex:1 cellIndex:0]; 55 | } 56 | [self dismissViewControllerAnimated:YES completion:nil]; 57 | }]; 58 | }]; 59 | }]; 60 | [self.tableViewDataSource reloadTableViewData]; 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/TableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.h 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface TableViewController : UIViewController 15 | 16 | @property (nonatomic, weak) IBOutlet UITableView *tableView; 17 | @property (nonatomic, strong, readonly) ZHTableViewDataSource *tableViewDataSource; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/TableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.m 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "TableViewController.h" 10 | 11 | @interface TableViewController () 12 | 13 | @property (nonatomic, strong) ZHTableViewDataSource *tableViewDataSource; 14 | 15 | @end 16 | 17 | @implementation TableViewController 18 | 19 | - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 20 | nibNameOrNil = nibNameOrNil ?: @"TableViewController"; 21 | nibBundleOrNil = nibBundleOrNil ?: [NSBundle mainBundle]; 22 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 23 | 24 | } 25 | return self; 26 | } 27 | 28 | - (void)viewDidLoad { 29 | [super viewDidLoad]; 30 | 31 | } 32 | 33 | - (ZHTableViewDataSource *)tableViewDataSource { 34 | if (!_tableViewDataSource) { 35 | _tableViewDataSource = [[ZHTableViewDataSource alloc] initWithTableView:self.tableView]; 36 | } 37 | return _tableViewDataSource; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/TableViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import 11 | #import "ReloadHeightViewController.h" 12 | #import "ReloadCellViewController.h" 13 | #import "ReloadCellDataViewController.h" 14 | #import "HiddenViewController.h" 15 | 16 | @interface ViewController () 17 | 18 | @property (nonatomic, weak) IBOutlet UITableView *tableView; 19 | @property (nonatomic, strong) ZHTableViewDataSource *tableViewDataSource; 20 | 21 | @end 22 | 23 | @implementation ViewController 24 | 25 | - (void)viewDidLoad { 26 | [super viewDidLoad]; 27 | [self.tableViewDataSource clearData]; 28 | __weak typeof(self) weakSelf = self; 29 | [self.tableViewDataSource addGroupWithCompletionHandle:^(ZHTableViewGroup *group) { 30 | __strong typeof(weakSelf) strongSelf = weakSelf; 31 | [strongSelf addReloadHeightInGroup:group]; 32 | [strongSelf addReloadCellInGroup:group]; 33 | [strongSelf addReloadDataInGroup:group]; 34 | [strongSelf addHiddenInGroup:group]; 35 | }]; 36 | [self.tableViewDataSource reloadTableViewData]; 37 | 38 | } 39 | 40 | - (void)addReloadHeightInGroup:(ZHTableViewGroup *)group { 41 | [group addCellWithCompletionHandle:^(ZHTableViewCell *tableViewCell) { 42 | tableViewCell.anyClass = [UITableViewCell class]; 43 | tableViewCell.identifier = @"UITableViewCell"; 44 | [tableViewCell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 45 | cell.textLabel.text = @"刷新高度"; 46 | NSLog(@"%@",cell); 47 | }]; 48 | [tableViewCell setDidSelectRowCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 49 | ReloadHeightViewController *controller = [[ReloadHeightViewController alloc] initWithNibName:nil bundle:nil]; 50 | [self.navigationController pushViewController:controller animated:YES]; 51 | }]; 52 | }]; 53 | } 54 | 55 | - (void)addReloadCellInGroup:(ZHTableViewGroup *)group { 56 | [group addCellWithCompletionHandle:^(ZHTableViewCell *tableViewCell) { 57 | tableViewCell.anyClass = [UITableViewCell class]; 58 | tableViewCell.identifier = @"UITableViewCell"; 59 | [tableViewCell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 60 | cell.textLabel.text = @"刷新Cell"; 61 | }]; 62 | [tableViewCell setDidSelectRowCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 63 | ReloadCellViewController *controller = [[ReloadCellViewController alloc] initWithNibName:nil bundle:nil]; 64 | [self.navigationController pushViewController:controller animated:YES]; 65 | }]; 66 | }]; 67 | } 68 | 69 | - (void)addReloadDataInGroup:(ZHTableViewGroup *)group { 70 | [group addCellWithCompletionHandle:^(ZHTableViewCell *tableViewCell) { 71 | tableViewCell.anyClass = [UITableViewCell class]; 72 | tableViewCell.identifier = @"UITableViewCell"; 73 | [tableViewCell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 74 | cell.textLabel.text = @"刷新数据"; 75 | }]; 76 | [tableViewCell setDidSelectRowCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 77 | ReloadCellDataViewController *controller = [[ReloadCellDataViewController alloc] initWithNibName:nil bundle:nil]; 78 | [self.navigationController pushViewController:controller animated:YES]; 79 | }]; 80 | }]; 81 | } 82 | 83 | - (void)addHiddenInGroup:(ZHTableViewGroup *)group { 84 | [group addCellWithCompletionHandle:^(ZHTableViewCell *tableViewCell) { 85 | tableViewCell.anyClass = [UITableViewCell class]; 86 | tableViewCell.identifier = @"UITableViewCell"; 87 | [tableViewCell setConfigCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 88 | cell.textLabel.text = @"显示和隐藏"; 89 | }]; 90 | [tableViewCell setDidSelectRowCompletionHandle:^(UITableViewCell *cell, NSIndexPath *indexPath) { 91 | HiddenViewController *controller = [[HiddenViewController alloc] initWithNibName:nil bundle:nil]; 92 | [self.navigationController pushViewController:controller animated:YES]; 93 | }]; 94 | }]; 95 | } 96 | 97 | - (ZHTableViewDataSource *)tableViewDataSource { 98 | if (!_tableViewDataSource) { 99 | _tableViewDataSource = [[ZHTableViewDataSource alloc] initWithTableView:self.tableView]; 100 | } 101 | return _tableViewDataSource; 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ZHTableViewGroupExample 4 | // 5 | // Created by josercc on 2020/2/25. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | NSString * appDelegateClassName; 14 | @autoreleasepool { 15 | // Setup code that might create autoreleased objects goes here. 16 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 17 | } 18 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 19 | } 20 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHAutoConfigurationCollectionViewDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHAutoConfigurationCollectionViewDelegate.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/4/20. 6 | // 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, ZHCollectionViewCustomHeightType) { 12 | ZHCollectionViewCustomHeightTypeCell, 13 | ZHCollectionViewCustomHeightTypeHeader, 14 | ZHCollectionViewCustomHeightTypeFooter 15 | }; 16 | 17 | @class ZHCollectionViewDataSource; 18 | 19 | /** 20 | 自动配置 UICollectionView 的数据源和代理 21 | 默认实现 UICollectionView 的数据源方法和代理方法如下 22 | */ 23 | @interface ZHAutoConfigurationCollectionViewDelegate : NSObject 24 | 25 | /** 26 | 初始化自动配置ZHAutoConfigurationCollectionViewDelegate对象 27 | 28 | @param dataSource ZHCollectionViewDataSource 29 | @return ZHAutoConfigurationCollectionViewDelegate 30 | */ 31 | - (instancetype)initWithDataSource:(ZHCollectionViewDataSource *)dataSource; 32 | 33 | @end 34 | 35 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHAutoConfigurationCollectionViewDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHAutoConfigurationCollectionViewDelegate.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/4/20. 6 | // 7 | // 8 | 9 | #import "ZHAutoConfigurationCollectionViewDelegate.h" 10 | #import "ZHCollectionViewDataSource.h" 11 | 12 | @interface ZHAutoConfigurationCollectionViewDelegate () 13 | 14 | @property (nonatomic, weak) ZHCollectionViewDataSource *dataSource; 15 | 16 | @end 17 | 18 | 19 | @implementation ZHAutoConfigurationCollectionViewDelegate { 20 | 21 | } 22 | 23 | - (instancetype)initWithDataSource:(ZHCollectionViewDataSource *)dataSource { 24 | if (self = [super init]) { 25 | _dataSource = dataSource; 26 | } 27 | return self; 28 | } 29 | 30 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 31 | return [ZHCollectionViewDataSource numberOfSectionsWithDataSource:_dataSource]; 32 | } 33 | 34 | - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 35 | return [ZHCollectionViewDataSource cellForRowAtWithDataSource:_dataSource indexPath:indexPath]; 36 | } 37 | 38 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 39 | return [ZHCollectionViewDataSource numberOfRowsInSectionWithDataSource:_dataSource section:section]; 40 | } 41 | 42 | - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { 43 | if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { 44 | return [ZHCollectionViewDataSource viewForHeaderInSectionWithDataSource:_dataSource section:indexPath.section]; 45 | } else { 46 | return [ZHCollectionViewDataSource viewForFooterInSectionWithDataSource:_dataSource section:indexPath.section]; 47 | } 48 | } 49 | 50 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 51 | [collectionView deselectItemAtIndexPath:indexPath animated:YES]; 52 | [ZHCollectionViewDataSource didSelectRowAtWithDataSource:_dataSource indexPath:indexPath]; 53 | } 54 | 55 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { 56 | return [ZHCollectionViewDataSource sizeForItemWithDataSource:_dataSource indexPath:indexPath]; 57 | } 58 | 59 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section { 60 | return [ZHCollectionViewDataSource referenceSizeForHeaderFooterWithDataSource:_dataSource style:ZHCollectionViewHeaderFooterStyleHeader section:section]; 61 | } 62 | 63 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section { 64 | return [ZHCollectionViewDataSource referenceSizeForHeaderFooterWithDataSource:_dataSource style:ZHCollectionViewHeaderFooterStyleFooter section:section]; 65 | } 66 | 67 | - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { 68 | ZHCollectionViewGroup *group = _dataSource.groups[section]; 69 | return group.sectionEdgeInsets; 70 | } 71 | 72 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 73 | if (_dataSource.scrollViewDidEndDraggingWillDecelerate) { 74 | _dataSource.scrollViewDidEndDraggingWillDecelerate(scrollView, decelerate); 75 | } 76 | 77 | } 78 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 79 | if (_dataSource.scrollViewDidEndDecelerating) { 80 | _dataSource.scrollViewDidEndDecelerating(scrollView); 81 | } 82 | } 83 | 84 | - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { 85 | if (_dataSource.scrollViewDidEndScrollingAnimation) { 86 | _dataSource.scrollViewDidEndScrollingAnimation(scrollView); 87 | } 88 | } 89 | 90 | @end 91 | 92 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHAutoConfigurationTableViewDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHAutoConfigurationTableViewDelegate.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/4/20. 6 | // 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, ZHTableViewCustomHeightType) { 12 | ZHTableViewCustomHeightTypeCell, 13 | ZHTableViewCustomHeightTypeHeader, 14 | ZHTableViewCustomHeightTypeFooter 15 | }; 16 | 17 | @class ZHTableViewDataSource; 18 | 19 | /** 20 | 自动配置 UITableView 的数据源和代理 21 | 默认实现 UITableView 的数据源方法和代理方法如下 22 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 23 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 24 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 25 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 26 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section; 27 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 28 | - (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 29 | - (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section 30 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 31 | */ 32 | @interface ZHAutoConfigurationTableViewDelegate : NSObject 33 | 34 | /** 35 | 初始化自动配置ZHAutoConfigurationTableViewDelegate对象 36 | 37 | @param dataSource ZHTableViewDataSource 38 | @return ZHAutoConfigurationTableViewDelegate 39 | */ 40 | - (instancetype)initWithDataSource:(ZHTableViewDataSource *)dataSource; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHAutoConfigurationTableViewDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHAutoConfigurationTableViewDelegate.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/4/20. 6 | // 7 | // 8 | 9 | #import "ZHAutoConfigurationTableViewDelegate.h" 10 | #import "ZHTableViewDataSource.h" 11 | 12 | @interface ZHAutoConfigurationTableViewDelegate () 13 | 14 | @property (nonatomic, weak) ZHTableViewDataSource *dataSource; 15 | 16 | @end 17 | 18 | @implementation ZHAutoConfigurationTableViewDelegate 19 | 20 | - (instancetype)initWithDataSource:(ZHTableViewDataSource *)dataSource { 21 | if (self = [super init]) { 22 | _dataSource = dataSource; 23 | } 24 | return self; 25 | } 26 | 27 | - (ZHTableViewDataSourceCustomHeightCompletionHandle)completionHandleWithTableView:(UITableView *)tableView 28 | heightAtIndexPath:(NSIndexPath *)indexPath { 29 | return ^CGFloat(ZHTableViewBaseModel *model) { 30 | if (!model.customHeightCompletionHandle) { 31 | return model.height; 32 | } 33 | NSIndexPath *reallyIndexPath = [ZHTableViewDataSource indexPathWithDataSource:self->_dataSource 34 | indexPath:indexPath]; 35 | return model.customHeightCompletionHandle(tableView,reallyIndexPath,model); 36 | };; 37 | } 38 | 39 | - (CGFloat)tableView:(UITableView *)tableView 40 | heightForRowAtIndexPath:(NSIndexPath *)indexPath { 41 | ZHTableViewDataSourceCustomHeightCompletionHandle handle = [self completionHandleWithTableView:tableView 42 | heightAtIndexPath:indexPath]; 43 | CGFloat height = [ZHTableViewDataSource heightForRowAtDataSource:_dataSource 44 | indexPath:indexPath 45 | customHeightCompletionHandle:handle]; 46 | if (_dataSource.heightForRowAtIndexPath) { 47 | _dataSource.heightForRowAtIndexPath(tableView, indexPath, height); 48 | } 49 | return height; 50 | } 51 | - (CGFloat)tableView:(UITableView *)tableView 52 | heightForHeaderInSection:(NSInteger)section { 53 | CGFloat height = [ZHTableViewDataSource heightForHeaderInSectionWithDataSource:_dataSource 54 | section:section 55 | customHeightCompletionHandle:[self completionHandleWithTableView:tableView 56 | heightAtIndexPath:[NSIndexPath indexPathForRow:0 57 | inSection:section]]]; 58 | if (_dataSource.heightForHeaderInSection) { 59 | _dataSource.heightForHeaderInSection(tableView, section, height); 60 | } 61 | return height; 62 | } 63 | - (CGFloat)tableView:(UITableView *)tableView 64 | heightForFooterInSection:(NSInteger)section { 65 | CGFloat height = [ZHTableViewDataSource heightForFooterInSectionWithDataSource:_dataSource section:section customHeightCompletionHandle:[self completionHandleWithTableView:tableView heightAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]]]; 66 | if (_dataSource.heightForFooterInSection) { 67 | _dataSource.heightForFooterInSection(tableView, section, height); 68 | } 69 | return height; 70 | } 71 | - (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 72 | return [ZHTableViewDataSource viewForHeaderInSectionWithDataSource:_dataSource section:section]; 73 | } 74 | - (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { 75 | return [ZHTableViewDataSource viewForFooterInSectionWithDataSource:_dataSource section:section]; 76 | } 77 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 78 | return [ZHTableViewDataSource numberOfRowsInSectionWithDataSource:_dataSource section:section]; 79 | } 80 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 81 | return [ZHTableViewDataSource cellForRowAtWithDataSource:_dataSource indexPath:indexPath]; 82 | } 83 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 84 | return [ZHTableViewDataSource numberOfSectionsWithDataSource:_dataSource]; 85 | } 86 | 87 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 88 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 89 | [ZHTableViewDataSource didSelectRowAtWithDataSource:_dataSource indexPath:indexPath]; 90 | } 91 | 92 | - (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section { 93 | 94 | } 95 | 96 | - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section { 97 | 98 | } 99 | 100 | - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 101 | [ZHTableViewDataSource dataSource:_dataSource willDisplayCell:cell forRowAtIndexPath:indexPath]; 102 | } 103 | 104 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 105 | if (_dataSource.scrollViewDidScrollCompletionHandle) { 106 | _dataSource.scrollViewDidScrollCompletionHandle(scrollView); 107 | } 108 | } 109 | 110 | - (void)scrollViewDidZoom:(UIScrollView *)scrollView { 111 | if (_dataSource.scrollViewDidZoom) { 112 | _dataSource.scrollViewDidZoom(scrollView); 113 | } 114 | } 115 | 116 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 117 | if (_dataSource.scrollViewWillBeginDraggingCompletionHandle) { 118 | _dataSource.scrollViewWillBeginDraggingCompletionHandle(scrollView); 119 | } 120 | } 121 | 122 | - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { 123 | if (_dataSource.scrollViewWillEndDragging) { 124 | _dataSource.scrollViewWillEndDragging(scrollView, velocity, targetContentOffset); 125 | } 126 | } 127 | 128 | 129 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 130 | if (_dataSource.scrollViewDidEndDragging) { 131 | _dataSource.scrollViewDidEndDragging(scrollView, decelerate); 132 | } 133 | } 134 | 135 | - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView { 136 | if (_dataSource.scrollViewWillBeginDecelerating) { 137 | _dataSource.scrollViewWillBeginDecelerating(scrollView); 138 | } 139 | } 140 | 141 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 142 | if (_dataSource.scrollViewDidEndDecelerating) { 143 | _dataSource.scrollViewDidEndDecelerating(scrollView); 144 | } 145 | } 146 | 147 | - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { 148 | if (_dataSource.scrollViewDidEndScrollingAnimation) { 149 | _dataSource.scrollViewDidEndScrollingAnimation(scrollView); 150 | } 151 | } 152 | 153 | - (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { 154 | if (_dataSource.viewForZoomingInScrollView) { 155 | return _dataSource.viewForZoomingInScrollView(scrollView); 156 | } 157 | return nil; 158 | } 159 | 160 | - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view { 161 | if (_dataSource.scrollViewWillBeginZooming) { 162 | _dataSource.scrollViewWillBeginZooming(scrollView,view); 163 | } 164 | } 165 | 166 | - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view atScale:(CGFloat)scale { 167 | if (_dataSource.scrollViewDidEndZooming) { 168 | _dataSource.scrollViewDidEndZooming(scrollView,view,scale); 169 | } 170 | } 171 | 172 | - (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView { 173 | if (_dataSource.scrollViewShouldScrollToTop) { 174 | return _dataSource.scrollViewShouldScrollToTop(scrollView); 175 | } 176 | return YES; 177 | } 178 | 179 | - (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView { 180 | if (_dataSource.scrollViewDidScrollToTop) { 181 | _dataSource.scrollViewDidScrollToTop(scrollView); 182 | } 183 | } 184 | 185 | - (void)scrollViewDidChangeAdjustedContentInset:(UIScrollView *)scrollView { 186 | if (_dataSource.scrollViewDidChangeAdjustedContentInset) { 187 | _dataSource.scrollViewDidChangeAdjustedContentInset(scrollView); 188 | } 189 | } 190 | 191 | @end 192 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHCollectionViewBaseModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHCollectionViewBaseModel.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2018/2/6. 6 | // 7 | // 8 | 9 | #import 10 | @class ZHCollectionViewBaseModel; 11 | 12 | typedef CGFloat (^ZHCollectionViewBaseModelCustomHeightCompletionHandle)(UICollectionView *collectionView, NSIndexPath *indexPath, ZHCollectionViewBaseModel *model); 13 | 14 | /** 15 | 配置 Cell Header Footer 的数据 Model 16 | */ 17 | @interface ZHCollectionViewBaseModel : NSObject 18 | 19 | /** 20 | 标识符 21 | */ 22 | @property (nonatomic, copy) NSString *identifier; 23 | /** 24 | 自定义类 Class 25 | */ 26 | @property (nonatomic, strong) Class anyClass; 27 | /** 28 | 高度 默认为 NSNotFound 29 | height 属性废弃 用size 30 | */ 31 | //@property (nonatomic, assign) CGFloat height; 32 | 33 | 34 | /** 35 | * 设置 UICollectionCell UICollectionReusableView 的大小 36 | * 默认 CGSizeZero 37 | */ 38 | @property (nonatomic, assign) CGSize size; 39 | 40 | /** 41 | * 自定义高度 42 | */ 43 | @property (nonatomic, copy) ZHCollectionViewBaseModelCustomHeightCompletionHandle customHeightCompletionHandle; 44 | 45 | @end 46 | 47 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHCollectionViewBaseModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHCollectionViewBaseModel.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2018/2/6. 6 | // 7 | // 8 | 9 | #import "ZHCollectionViewBaseModel.h" 10 | 11 | @implementation ZHCollectionViewBaseModel 12 | 13 | - (instancetype)init { 14 | if (self = [super init]) { 15 | _size = CGSizeZero; 16 | } 17 | return self; 18 | } 19 | 20 | @end 21 | 22 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHCollectionViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // ZHCollectionViewCell.h 4 | // Pods 5 | // 6 | // Created by 张行 on 2018/2/6. 7 | // 8 | // 9 | 10 | #import "ZHCollectionViewBaseModel.h" 11 | 12 | /** 13 | 注册 Cell 样式 14 | */ 15 | @interface ZHCollectionViewCell : ZHCollectionViewBaseModel 16 | 17 | /** 18 | Cell 的个数 默认为1 19 | */ 20 | @property (nonatomic, assign) NSInteger cellNumber; 21 | /** 22 | 配置 Cell的回调 23 | */ 24 | @property (nonatomic, copy) void(^configCompletionHandle)(CellType cell, NSIndexPath *indexPath); 25 | /** 26 | 点击 Cell 的回调 27 | */ 28 | @property (nonatomic, copy) void(^didSelectRowCompletionHandle)(CellType cell, NSIndexPath *indexPath); 29 | @property (nonatomic, copy) CGSize(^customSizeBlock)(CellType cell, NSIndexPath *indexPath); 30 | 31 | /** 32 | * 为了是支持泛型 33 | 34 | @param configCompletionHandle 设置的Block 35 | */ 36 | - (void)setConfigCompletionHandle:(void (^)(CellType cell, NSIndexPath * indexPath))configCompletionHandle; 37 | 38 | /** 39 | * 为了支持泛型 40 | 41 | @param didSelectRowCompletionHandle 点击回调的block 42 | */ 43 | - (void)setDidSelectRowCompletionHandle:(void (^)(CellType cell, NSIndexPath * indexPath))didSelectRowCompletionHandle; 44 | 45 | /** 46 | 点击所在的 Cell 的执行方法 47 | 48 | @param cell 点击的 Cell 49 | @param indexPath 点击 cell 所在的索引 50 | */ 51 | - (void)didSelectRowAtWithCell:(CellType)cell 52 | indexPath:(NSIndexPath *)indexPath; 53 | 54 | /** 55 | 配置 Cell 的执行方法 56 | 57 | @param cell 配置的 Cell 58 | @param indexPath 配置 Cell 所在的索引 59 | */ 60 | - (void)configCellWithCell:(CellType)cell 61 | indexPath:(NSIndexPath *)indexPath; 62 | 63 | /** 64 | 一个方法配置所有的参数 65 | 66 | @param cellNumber cell 的数量 67 | @param identifier 标识符 68 | @param anyClass cell 的类名 69 | @param size 高度 70 | @param configCompletionHandle 配置 cell 71 | @param didSelectRowCompletionHandle 点击 cell 方法 72 | */ 73 | - (void)configurationCellWithCellNumber:(NSUInteger)cellNumber 74 | identifier:(NSString *)identifier 75 | anyClass:(Class)anyClass 76 | size:(CGSize)size 77 | configCompletionHandle:(void(^)(CellType cell, NSIndexPath *indexPath))configCompletionHandle 78 | didSelectRowCompletionHandle:(void(^)(CellType cell, NSIndexPath *indexPath))didSelectRowCompletionHandle; 79 | 80 | @end 81 | 82 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHCollectionViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHCollectionViewCell.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2018/2/6. 6 | // 7 | // 8 | 9 | #import "ZHCollectionViewCell.h" 10 | 11 | @implementation ZHCollectionViewCell { 12 | } 13 | 14 | - (instancetype)init { 15 | if (self = [super init]) { 16 | _cellNumber = 1; 17 | } 18 | return self; 19 | } 20 | 21 | - (void)setConfigCompletionHandle:(void (^)(UICollectionViewCell *, NSIndexPath *))configCompletionHandle { 22 | _configCompletionHandle = configCompletionHandle; 23 | } 24 | 25 | - (void)setDidSelectRowCompletionHandle:(void (^)(UICollectionViewCell *, NSIndexPath *))didSelectRowCompletionHandle { 26 | _didSelectRowCompletionHandle = didSelectRowCompletionHandle; 27 | } 28 | 29 | - (void)didSelectRowAtWithCell:(UICollectionViewCell *)cell 30 | indexPath:(NSIndexPath *)indexPath { 31 | if (!self.didSelectRowCompletionHandle) { 32 | return; 33 | } 34 | self.didSelectRowCompletionHandle(cell,indexPath); 35 | } 36 | 37 | - (void)configCellWithCell:(UICollectionViewCell *)cell 38 | indexPath:(NSIndexPath *)indexPath { 39 | if (!self.configCompletionHandle) { 40 | return; 41 | } 42 | self.configCompletionHandle(cell,indexPath); 43 | } 44 | 45 | - (void)configurationCellWithCellNumber:(NSUInteger)cellNumber 46 | identifier:(NSString *)identifier 47 | anyClass:(Class)anyClass 48 | size:(CGSize)size 49 | configCompletionHandle:(void (^)(UICollectionViewCell *, NSIndexPath *))configCompletionHandle 50 | didSelectRowCompletionHandle:(void (^)(UICollectionViewCell *, NSIndexPath *))didSelectRowCompletionHandle { 51 | self.cellNumber = cellNumber; 52 | self.identifier = identifier; 53 | self.anyClass = anyClass; 54 | self.size = size; 55 | self.configCompletionHandle = configCompletionHandle; 56 | self.didSelectRowCompletionHandle = didSelectRowCompletionHandle; 57 | } 58 | 59 | @end 60 | 61 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHCollectionViewDataSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHCollectionViewDataSource.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2018/2/6. 6 | // 7 | // 8 | 9 | #import 10 | #import "ZHCollectionViewGroup.h" 11 | #import "ZHAutoConfigurationCollectionViewDelegate.h" 12 | 13 | /** 14 | 添加分组的回调 15 | 16 | @param group 创建的分组对象 17 | */ 18 | typedef void(^ZHCollectionViewDataSourceAddGroupCompletionHandle)(ZHCollectionViewGroup *group); 19 | 20 | /** 21 | 自定义高度的回调 22 | 23 | @return 自定义算法返回的高度 24 | */ 25 | typedef CGFloat (^ZHCollectionViewDataSourceCustomHeightCompletionHandle)(ZHCollectionViewBaseModel *model); 26 | 27 | /** 28 | 进行 UICollectionView 进行数据托管的数据源 29 | */ 30 | @interface ZHCollectionViewDataSource : NSObject 31 | 32 | /** 33 | 自动配置 UICollectionView 的 DataSource 和 Delegate 默认为 YES 34 | */ 35 | @property (nonatomic, assign, getter=isAutoConfigurationCollectionViewDelegate) BOOL autoConfigurationCollectionViewDelegate; 36 | 37 | @property (nonatomic, strong, readonly) NSMutableArray *groups; 38 | 39 | /** 40 | 唯一的初始化ZHCollectionViewDataSource 41 | 42 | @param CollectionView 托管的 UICollectionView 的对象 必须存在 43 | @return ZHCollectionViewDataSource的对象 44 | */ 45 | - (instancetype)initWithCollectionView:(UICollectionView *)CollectionView; 46 | 47 | /** 48 | 添加一个分组 49 | 50 | @param completionHandle 返回新注册的分组对象 可以进行配置 51 | */ 52 | - (void)addGroupWithCompletionHandle:(ZHCollectionViewDataSourceAddGroupCompletionHandle)completionHandle; 53 | 54 | /** 55 | 进行刷新 UICollectionView 56 | */ 57 | - (void)reloadCollectionViewData; 58 | 59 | /** 60 | 获取分组Cell的个数 如果autoConfigurationCollectionViewDelegate = YES 此方法不用调用 61 | 62 | @param dataSource ZHCollectionViewDataSource数据源 63 | @param section 所在组索引 64 | @return 分组 Cell 的个数 65 | */ 66 | + (NSInteger)numberOfRowsInSectionWithDataSource:(ZHCollectionViewDataSource *)dataSource section:(NSInteger)section; 67 | 68 | /** 69 | 获取对应索引的UICollectionViewCell 如果autoConfigurationCollectionViewDelegate = YES 此方法不用调用 70 | 71 | @param dataSource ZHCollectionViewDataSource数据源 72 | @param indexPath 所在的索引 73 | @return UICollectionViewCell 74 | */ 75 | + (UICollectionViewCell *)cellForRowAtWithDataSource:(ZHCollectionViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath; 76 | 77 | /** 78 | 获取分组的个数 如果autoConfigurationCollectionViewDelegate = YES 此方法不用调用 79 | 80 | @param dataSource ZHCollectionViewDataSource的数据源 81 | @return 分组的个数 82 | */ 83 | + (NSInteger)numberOfSectionsWithDataSource:(ZHCollectionViewDataSource *)dataSource; 84 | 85 | /** 86 | 点击 Cell 的回调 87 | 88 | @param dataSource ZHCollectionViewDataSource数据源 89 | @param indexPath 点击的索引 90 | */ 91 | + (void)didSelectRowAtWithDataSource:(ZHCollectionViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath; 92 | 93 | /** 94 | 获取Header 95 | 96 | @param dataSource ZHCollectionViewDataSource数据源 97 | @param section 分组的索引 98 | @return 分组 Header 试图 99 | */ 100 | + (UICollectionReusableView *)viewForHeaderInSectionWithDataSource:(ZHCollectionViewDataSource *)dataSource section:(NSInteger)section; 101 | /** 102 | 获取Footer 103 | 104 | @param dataSource ZHCollectionViewDataSource数据源 105 | @param section 分组的索引 106 | @return 分组 Footer 试图 107 | */ 108 | + (UICollectionReusableView *)viewForFooterInSectionWithDataSource:(ZHCollectionViewDataSource *)dataSource section:(NSInteger)section; 109 | 110 | /** 111 | 清空之前数据 112 | */ 113 | - (void)clearData; 114 | 115 | + (NSIndexPath *)indexPathWithDataSource:(ZHCollectionViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath; 116 | 117 | + (CGSize)sizeForItemWithDataSource:(ZHCollectionViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath; 118 | 119 | + (CGSize)referenceSizeForHeaderFooterWithDataSource:(ZHCollectionViewDataSource *)dataSource style:(ZHCollectionViewHeaderFooterStyle)style section:(NSUInteger)section; 120 | 121 | @property (nonatomic, copy) void (^scrollViewDidEndDraggingWillDecelerate)(UIScrollView *scrollView, BOOL willDecelerate); 122 | @property (nonatomic, copy) void (^scrollViewDidEndDecelerating)(UIScrollView *scrollView); 123 | @property (nonatomic, copy) void (^scrollViewDidEndScrollingAnimation)(UIScrollView *scrollView); 124 | 125 | @end 126 | 127 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHCollectionViewDataSource.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHCollectionViewDataSource.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2018/2/6. 6 | // 7 | // 8 | 9 | #import "ZHCollectionViewDataSource.h" 10 | #import "ZHAutoConfigurationCollectionViewDelegate.h" 11 | 12 | @interface ZHCollectionViewDataSource () 13 | 14 | @property (nonatomic, strong) NSMutableArray *groups; 15 | @property (nonatomic, weak) UICollectionView *collectionView; 16 | @property (nonatomic, strong) ZHAutoConfigurationCollectionViewDelegate *autoConfiguration; 17 | 18 | @end 19 | 20 | @implementation ZHCollectionViewDataSource { 21 | 22 | } 23 | 24 | - (void)dealloc { 25 | NSLog(@"ZHCollectionViewDataSource 释放了"); 26 | } 27 | 28 | - (instancetype)initWithCollectionView:(UICollectionView *)CollectionView { 29 | if (self = [super init]) { 30 | _collectionView = CollectionView; 31 | _autoConfigurationCollectionViewDelegate = YES; 32 | } 33 | return self; 34 | } 35 | 36 | - (void)addGroupWithCompletionHandle:(ZHCollectionViewDataSourceAddGroupCompletionHandle)completionHandle { 37 | ZHCollectionViewGroup *group = [[ZHCollectionViewGroup alloc] init]; 38 | if (completionHandle) { 39 | completionHandle(group); 40 | } 41 | [self.groups addObject:group]; 42 | } 43 | 44 | - (void)reloadCollectionViewData { 45 | if (!self.collectionView.dataSource && self.isAutoConfigurationCollectionViewDelegate) { 46 | self.collectionView.dataSource = self.autoConfiguration; 47 | } 48 | if (!self.collectionView.delegate && self.isAutoConfigurationCollectionViewDelegate) { 49 | self.collectionView.delegate = self.autoConfiguration; 50 | } 51 | [self registerClasss]; 52 | [self.collectionView reloadData]; 53 | } 54 | 55 | + (NSInteger)numberOfRowsInSectionWithDataSource:(ZHCollectionViewDataSource *)dataSource 56 | section:(NSInteger)section { 57 | ZHCollectionViewGroup *group = [self groupForSectionWithDataSource:dataSource section:section]; 58 | if (!group) { 59 | return 0; 60 | } 61 | return group.cellCount; 62 | } 63 | 64 | + (UICollectionViewCell *)cellForRowAtWithDataSource:(ZHCollectionViewDataSource *)dataSource 65 | indexPath:(NSIndexPath *)indexPath { 66 | ZHCollectionViewGroup *group = [self groupForSectionWithDataSource:dataSource section:indexPath.section]; 67 | UICollectionViewCell *cell = [[UICollectionViewCell alloc] initWithFrame:CGRectZero]; 68 | if (!group) { 69 | return cell; 70 | } 71 | UICollectionViewCell *resultCell = [group cellForCollectionViewWithCollectionView:dataSource.collectionView indexPath:indexPath]; 72 | if (!resultCell) { 73 | return cell; 74 | } 75 | return resultCell; 76 | } 77 | 78 | + (NSInteger)numberOfSectionsWithDataSource:(ZHCollectionViewDataSource *)dataSource { 79 | if (!dataSource) { 80 | return 0; 81 | } 82 | return dataSource.groups.count; 83 | } 84 | 85 | + (void)didSelectRowAtWithDataSource:(ZHCollectionViewDataSource *)dataSource 86 | indexPath:(NSIndexPath *)indexPath { 87 | ZHCollectionViewCell *CollectionViewCell = [self cellForIndexPath:dataSource indexPath:indexPath]; 88 | if (!CollectionViewCell) { 89 | return; 90 | } 91 | UICollectionViewCell *cell = [self cellForRowAtWithDataSource:dataSource indexPath:indexPath]; 92 | ZHCollectionViewGroup *group = [self groupForSectionWithDataSource:dataSource section:indexPath.section]; 93 | [CollectionViewCell didSelectRowAtWithCell:cell indexPath:[group indexPathWithCell:CollectionViewCell indexPath:indexPath]]; 94 | } 95 | 96 | + (UICollectionReusableView *)viewForHeaderInSectionWithDataSource:(ZHCollectionViewDataSource *)dataSource 97 | section:(NSInteger)section { 98 | return [self viewHeaderFooterInSectionWithDtaSource:dataSource section:section style:ZHCollectionViewHeaderFooterStyleHeader]; 99 | } 100 | 101 | + (UICollectionReusableView *)viewForFooterInSectionWithDataSource:(ZHCollectionViewDataSource *)dataSource 102 | section:(NSInteger)section { 103 | return [self viewHeaderFooterInSectionWithDtaSource:dataSource section:section style:ZHCollectionViewHeaderFooterStyleFooter]; 104 | } 105 | 106 | - (void)clearData { 107 | [self.groups removeAllObjects]; 108 | } 109 | 110 | + (UICollectionReusableView *)viewHeaderFooterInSectionWithDtaSource:(ZHCollectionViewDataSource *)dataSource 111 | section:(NSInteger)section style:(ZHCollectionViewHeaderFooterStyle)style { 112 | ZHCollectionViewGroup *group = [self groupForSectionWithDataSource:dataSource section:section]; 113 | if (!group) { 114 | return nil; 115 | } 116 | return [group headerFooterForStyle:style collectionView:dataSource.collectionView section:section]; 117 | } 118 | 119 | + (CGFloat)heightWithCustomHandle:(CGFloat)height 120 | customCompletionHandle:(ZHCollectionViewDataSourceCustomHeightCompletionHandle)customCompletionHandle 121 | baseModel:(ZHCollectionViewBaseModel *)baseModel { 122 | if (height != 0 && height != NSNotFound && height != CGFLOAT_MAX) { 123 | return height; 124 | } 125 | if (customCompletionHandle) { 126 | return customCompletionHandle(baseModel); 127 | } 128 | return 44; 129 | } 130 | 131 | 132 | + (ZHCollectionViewGroup *)groupForSectionWithDataSource:(ZHCollectionViewDataSource *)dataSource 133 | section:(NSInteger)section { 134 | if (!dataSource) { 135 | return nil; 136 | } 137 | if (dataSource.groups.count <= section) { 138 | return nil; 139 | } 140 | return dataSource.groups[section]; 141 | } 142 | 143 | + (ZHCollectionViewCell *)cellForIndexPath:(ZHCollectionViewDataSource *)dataSource 144 | indexPath:(NSIndexPath *)indexPath { 145 | ZHCollectionViewGroup *group = [self groupForSectionWithDataSource:dataSource section:indexPath.section]; 146 | if (!group) { 147 | return nil; 148 | } 149 | return [group CollectionViewCellForIndexPath:indexPath]; 150 | } 151 | 152 | + (NSIndexPath *)indexPathWithDataSource:(ZHCollectionViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath { 153 | ZHCollectionViewGroup *group = [self groupForSectionWithDataSource:dataSource section:indexPath.section]; 154 | ZHCollectionViewCell *CollectionViewCell = [self cellForIndexPath:dataSource indexPath:indexPath]; 155 | return [group indexPathWithCell:CollectionViewCell indexPath:indexPath]; 156 | } 157 | 158 | + (CGSize)sizeForItemWithDataSource:(ZHCollectionViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath { 159 | ZHCollectionViewCell *cell = [self cellForIndexPath:dataSource indexPath:indexPath]; 160 | if (!CGSizeEqualToSize(cell.size, CGSizeZero)) { 161 | return cell.size; 162 | } 163 | UICollectionViewCell *collectionViewCell = [dataSource collectionViewWithClass:cell.anyClass]; 164 | [cell configCellWithCell:collectionViewCell indexPath:indexPath]; 165 | return [collectionViewCell sizeThatFits:[dataSource sizeFit]]; 166 | } 167 | 168 | + (CGSize)referenceSizeForHeaderFooterWithDataSource:(ZHCollectionViewDataSource *)dataSource style:(ZHCollectionViewHeaderFooterStyle)style section:(NSUInteger)section { 169 | ZHCollectionViewGroup *group = [self groupForSectionWithDataSource:dataSource section:section]; 170 | ZHCollectionViewHeaderFooter *headerFooter = style == ZHCollectionViewHeaderFooterStyleHeader ? group.header : group.footer; 171 | if (!CGSizeEqualToSize(headerFooter.size, CGSizeZero)) { 172 | return headerFooter.size; 173 | } 174 | UICollectionReusableView *view = [[headerFooter.anyClass alloc] initWithFrame:CGRectZero]; 175 | [headerFooter setHeaderFooter:view section:section]; 176 | return [view sizeThatFits:[dataSource sizeFit]]; 177 | } 178 | 179 | - (UICollectionViewCell *)collectionViewWithClass:(Class)class { 180 | UICollectionViewCell *cell = [[class alloc] initWithFrame:CGRectZero]; 181 | return cell; 182 | } 183 | 184 | - (CGSize)sizeFit { 185 | return CGSizeMake(CGRectGetWidth(_collectionView.frame), CGFLOAT_MAX); 186 | } 187 | 188 | - (void)registerClasss { 189 | for (ZHCollectionViewGroup *group in self.groups) { 190 | [group registerHeaderFooterCellWithCollectionView:self.collectionView]; 191 | } 192 | } 193 | 194 | - (NSMutableArray *)groups { 195 | if (!_groups) { 196 | _groups = [NSMutableArray array]; 197 | } 198 | return _groups; 199 | } 200 | 201 | - (ZHAutoConfigurationCollectionViewDelegate *)autoConfiguration { 202 | if (!_autoConfiguration) { 203 | _autoConfiguration = [[ZHAutoConfigurationCollectionViewDelegate alloc] initWithDataSource:self]; 204 | } 205 | return _autoConfiguration; 206 | } 207 | 208 | @end 209 | 210 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHCollectionViewGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHCollectionViewGroup.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2018/2/6. 6 | // 7 | // 8 | 9 | #import 10 | #import "ZHCollectionViewHeaderFooter.h" 11 | #import "ZHCollectionViewCell.h" 12 | 13 | typedef void(^ZHCollectionViewGroupAddCellCompletionHandle)(ZHCollectionViewCell *cell); 14 | typedef void(^ZHCollectionViewGroupAddHeaderFooterCompletionHandle)(ZHCollectionViewHeaderFooter *headerFooter); 15 | 16 | @interface ZHCollectionViewGroup : NSObject 17 | 18 | @property (nonatomic, strong) ZHCollectionViewHeaderFooter *header; 19 | @property (nonatomic, strong) ZHCollectionViewHeaderFooter *footer; 20 | @property (nonatomic, assign, readonly) NSInteger cellCount; 21 | @property (nonatomic, strong, readonly) NSMutableArray *cells; 22 | @property (nonatomic, assign) UIEdgeInsets sectionEdgeInsets; 23 | 24 | - (void)registerHeaderFooterCellWithCollectionView:(UICollectionView *)CollectionView; 25 | 26 | - (UICollectionViewCell *)cellForCollectionViewWithCollectionView:(UICollectionView *)CollectionView indexPath:(NSIndexPath *)indexPath; 27 | 28 | - (void)addCellWithCompletionHandle:(ZHCollectionViewGroupAddCellCompletionHandle)completionHandle; 29 | 30 | - (void)addHeaderWithCompletionHandle:(ZHCollectionViewGroupAddHeaderFooterCompletionHandle)completionHandle; 31 | 32 | - (void)addFooterWithCompletionHandle:(ZHCollectionViewGroupAddHeaderFooterCompletionHandle)completionHandle; 33 | 34 | - (ZHCollectionViewCell *)CollectionViewCellForIndexPath:(NSIndexPath *)indexPath; 35 | 36 | - (UICollectionReusableView *)headerFooterForStyle:(ZHCollectionViewHeaderFooterStyle)style collectionView:(UICollectionView *)collectionView section:(NSUInteger)section; 37 | 38 | - (NSIndexPath *)indexPathWithCell:(ZHCollectionViewCell *)cell indexPath:(NSIndexPath *)indexPath; 39 | @end 40 | 41 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHCollectionViewGroup.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHCollectionViewGroup.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2018/2/6. 6 | // 7 | // 8 | 9 | #import "ZHCollectionViewGroup.h" 10 | 11 | @interface ZHCollectionViewGroup () 12 | 13 | @property (nonatomic, strong) NSMutableArray *cells; 14 | 15 | @end 16 | 17 | @implementation ZHCollectionViewGroup 18 | 19 | - (instancetype)init { 20 | if (self = [super init]) { 21 | _sectionEdgeInsets = UIEdgeInsetsZero; 22 | } 23 | return self; 24 | } 25 | 26 | - (void)registerHeaderFooterCellWithCollectionView:(UICollectionView *)collectionView { 27 | if (self.header && self.header.identifier) { 28 | [collectionView registerClass:self.header.anyClass forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:self.header.identifier]; 29 | } 30 | if (self.footer && self.footer.identifier) { 31 | [collectionView registerClass:self.footer.anyClass forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:self.footer.identifier]; 32 | } 33 | for (ZHCollectionViewCell *collectionViewCell in self.cells) { 34 | if (collectionViewCell.identifier) { 35 | [collectionView registerClass:collectionViewCell.anyClass forCellWithReuseIdentifier:collectionViewCell.identifier]; 36 | } 37 | } 38 | } 39 | 40 | - (void)addCellWithCompletionHandle:(ZHCollectionViewGroupAddCellCompletionHandle)completionHandle { 41 | ZHCollectionViewCell *cell = [[ZHCollectionViewCell alloc] init]; 42 | if (completionHandle) { 43 | completionHandle(cell); 44 | } 45 | [self.cells addObject:cell]; 46 | } 47 | 48 | - (void)addHeaderWithCompletionHandle:(ZHCollectionViewGroupAddHeaderFooterCompletionHandle)completionHandle { 49 | ZHCollectionViewHeaderFooter *header= [[ZHCollectionViewHeaderFooter alloc] initWithStyle:ZHCollectionViewHeaderFooterStyleHeader]; 50 | if (completionHandle) { 51 | completionHandle(header); 52 | } 53 | _header = header; 54 | } 55 | 56 | - (void)addFooterWithCompletionHandle:(ZHCollectionViewGroupAddHeaderFooterCompletionHandle)completionHandle { 57 | ZHCollectionViewHeaderFooter *footer = [[ZHCollectionViewHeaderFooter alloc] initWithStyle:ZHCollectionViewHeaderFooterStyleFooter]; 58 | if (completionHandle) { 59 | completionHandle(footer); 60 | } 61 | _footer = footer; 62 | } 63 | 64 | - (UICollectionViewCell *)cellForCollectionViewWithCollectionView:(UICollectionView *)collectionView indexPath:(NSIndexPath *)indexPath { 65 | if (!collectionView) { 66 | return nil; 67 | } 68 | ZHCollectionViewCell *collectionViewCell = [self CollectionViewCellForIndexPath:indexPath]; 69 | if (!collectionViewCell) { 70 | return nil; 71 | } 72 | if (!collectionViewCell.identifier) { 73 | return nil; 74 | } 75 | UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:collectionViewCell.identifier forIndexPath:indexPath]; 76 | [collectionViewCell configCellWithCell:cell indexPath:[self indexPathWithCell:collectionViewCell indexPath:indexPath]]; 77 | return cell; 78 | } 79 | 80 | - (NSIndexPath *)indexPathWithCell:(ZHCollectionViewCell *)cell indexPath:(NSIndexPath *)indexPath { 81 | __block NSUInteger startIndex = 0; 82 | [self.cells enumerateObjectsUsingBlock:^(ZHCollectionViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 83 | if (obj == cell) { 84 | *stop = YES; 85 | return; 86 | } 87 | startIndex += obj.cellNumber; 88 | }]; 89 | return [NSIndexPath indexPathForRow:indexPath.row - startIndex inSection:indexPath.section]; 90 | } 91 | 92 | - (ZHCollectionViewCell *)CollectionViewCellForIndexPath:(NSIndexPath *)indexPath { 93 | if (indexPath.row >= self.cellCount) { 94 | return nil; 95 | } 96 | NSInteger count = 0; 97 | ZHCollectionViewCell *CollectionViewCell; 98 | for (NSUInteger i = 0; i < self.cells.count; i ++) { 99 | ZHCollectionViewCell *cell = self.cells[i]; 100 | NSUInteger tempCount = count; 101 | count += cell.cellNumber; 102 | if (indexPath.row >= tempCount && indexPath.row < count) { 103 | CollectionViewCell = cell; 104 | break; 105 | } 106 | } 107 | return CollectionViewCell; 108 | } 109 | 110 | - (UICollectionReusableView *)headerFooterForStyle:(ZHCollectionViewHeaderFooterStyle)style collectionView:(UICollectionView *)collectionView section:(NSUInteger)section { 111 | if (!collectionView) { 112 | return nil; 113 | } 114 | ZHCollectionViewHeaderFooter *headerFooter; 115 | NSString *kind; 116 | switch (style) { 117 | case ZHCollectionViewHeaderFooterStyleHeader: { 118 | headerFooter = self.header; 119 | kind = UICollectionElementKindSectionHeader; 120 | } 121 | break; 122 | case ZHCollectionViewHeaderFooterStyleFooter: { 123 | headerFooter = self.footer; 124 | kind = UICollectionElementKindSectionFooter; 125 | } 126 | break; 127 | } 128 | if (!headerFooter) { 129 | return nil; 130 | } 131 | if (!headerFooter.identifier) { 132 | return nil; 133 | } 134 | UICollectionReusableView *headerFooterView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:headerFooter.identifier forIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]]; 135 | [headerFooter setHeaderFooter:headerFooterView section:section]; 136 | return headerFooterView; 137 | } 138 | 139 | 140 | - (NSMutableArray *)cells { 141 | if (!_cells) { 142 | _cells = [NSMutableArray array]; 143 | } 144 | return _cells; 145 | } 146 | 147 | - (NSInteger)cellCount { 148 | NSInteger count = 0; 149 | for (ZHCollectionViewCell *collectionViewCell in self.cells) { 150 | count += collectionViewCell.cellNumber; 151 | } 152 | return count; 153 | } 154 | 155 | @end 156 | 157 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHCollectionViewHeaderFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHCollectionVieweaderFooter.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2018/2/6. 6 | // 7 | // 8 | 9 | #import 10 | #import "ZHCollectionViewBaseModel.h" 11 | 12 | /** 13 | * 配置UICollectionVieweaderFooterView的回调 14 | 15 | @param headerFooterView 需要设置配置的UICollectionVieweaderFooterView 16 | @param section 需要配置的组 17 | */ 18 | typedef void(^ZHCollectionViewHeaderFooterCompletionHandle)(UICollectionReusableView *headerFooterView, NSUInteger section); 19 | 20 | typedef NS_ENUM(NSUInteger, ZHCollectionViewHeaderFooterStyle) { 21 | ZHCollectionViewHeaderFooterStyleHeader, 22 | ZHCollectionViewHeaderFooterStyleFooter 23 | }; 24 | 25 | @interface ZHCollectionViewHeaderFooter : ZHCollectionViewBaseModel 26 | 27 | @property (nonatomic, assign) ZHCollectionViewHeaderFooterStyle style; 28 | @property (nonatomic, copy) CGSize(^customSizeBlock)(HeaderFooter view, NSUInteger section); 29 | 30 | /** 31 | * 根据样式进行初始化ZHCollectionVieweaderFooter 32 | 33 | @param style 样式 34 | @return ZHCollectionVieweaderFooter 35 | */ 36 | - (instancetype)initWithStyle:(ZHCollectionViewHeaderFooterStyle)style; 37 | 38 | /** 39 | * 执行配置UICollectionVieweaderFooterView 40 | 41 | @param headerFooter UICollectionVieweaderFooterView的泛型 42 | @param section 配置所在的Section 43 | */ 44 | - (void)setHeaderFooter:(HeaderFooter)headerFooter section:(NSUInteger)section; 45 | 46 | /** 47 | * 配置Header的回调 48 | 49 | @param block 配置的Block 50 | */ 51 | - (void)configurationHeader:(void(^)(HeaderFooter header, NSUInteger section))block; 52 | /** 53 | * 配置Footer的回调 54 | 55 | @param block 配置的Block 56 | */ 57 | - (void)configurationFooter:(void(^)(HeaderFooter footer, NSUInteger section))block; 58 | 59 | @end 60 | 61 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHCollectionViewHeaderFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHCollectionViewHeaderFooter.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2018/2/6. 6 | // 7 | // 8 | 9 | #import "ZHCollectionViewHeaderFooter.h" 10 | 11 | @implementation ZHCollectionViewHeaderFooter { 12 | ZHCollectionViewHeaderFooterCompletionHandle _headerBlock; 13 | ZHCollectionViewHeaderFooterCompletionHandle _footerBlock; 14 | } 15 | 16 | - (instancetype)initWithStyle:(ZHCollectionViewHeaderFooterStyle)style { 17 | if (self = [super init]) { 18 | _style = style; 19 | } 20 | return self; 21 | } 22 | 23 | - (void)setHeaderFooter:(UICollectionReusableView *)headerFooter section:(NSUInteger)section { 24 | switch (self.style) { 25 | case ZHCollectionViewHeaderFooterStyleHeader: { 26 | if (_headerBlock) { 27 | _headerBlock(headerFooter,section); 28 | } 29 | } 30 | break; 31 | case ZHCollectionViewHeaderFooterStyleFooter: { 32 | if (_footerBlock) { 33 | _footerBlock(headerFooter,section); 34 | } 35 | } 36 | break; 37 | default: 38 | break; 39 | } 40 | } 41 | 42 | - (void)configurationHeader:(void (^)(UICollectionReusableView *header, NSUInteger section))block { 43 | _headerBlock = block; 44 | } 45 | 46 | -(void)configurationFooter:(void (^)(UICollectionReusableView *footer, NSUInteger section))block { 47 | _footerBlock = block; 48 | } 49 | 50 | @end 51 | 52 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewBaseModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewBaseModel.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/3/18. 6 | // 7 | // 8 | #import 9 | @class ZHTableViewBaseModel; 10 | 11 | typedef CGFloat (^ZHTableViewBaseModelCustomHeightCompletionHandle)(UITableView *tableView, NSIndexPath *indexPath, ZHTableViewBaseModel *model); 12 | 13 | /** 14 | 配置 Cell Header Footer 的数据 Model 15 | */ 16 | @interface ZHTableViewBaseModel : NSObject 17 | 18 | /** 19 | 标识符 20 | */ 21 | @property (nonatomic, copy) NSString *identifier; 22 | /** 23 | 自定义类 Class 24 | */ 25 | @property (nonatomic, strong) Class anyClass; 26 | /** 27 | 高度 默认为 NSNotFound 28 | */ 29 | @property (nonatomic, assign) CGFloat height; 30 | /** 31 | * 自定义高度 32 | */ 33 | @property (nonatomic, copy) ZHTableViewBaseModelCustomHeightCompletionHandle customHeightCompletionHandle; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewBaseModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewBaseModel.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/3/18. 6 | // 7 | // 8 | 9 | #import "ZHTableViewBaseModel.h" 10 | 11 | @implementation ZHTableViewBaseModel 12 | 13 | - (instancetype)init { 14 | if (self = [super init]) { 15 | _height = NSNotFound; 16 | } 17 | return self; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewCell.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/3/18. 6 | // 7 | // 8 | 9 | #import "ZHTableViewBaseModel.h" 10 | 11 | /** 12 | 注册 Cell 样式 13 | */ 14 | @interface ZHTableViewCell : ZHTableViewBaseModel 15 | 16 | /** 17 | Cell 的个数 默认为1 18 | */ 19 | @property (nonatomic, assign) NSInteger cellNumber; 20 | /** 21 | 配置 Cell的回调 22 | */ 23 | @property (nonatomic, copy) void(^configCompletionHandle)(CellType cell, NSIndexPath *indexPath); 24 | /** 25 | 点击 Cell 的回调 26 | */ 27 | @property (nonatomic, copy) void(^didSelectRowCompletionHandle)(CellType cell, NSIndexPath *indexPath); 28 | 29 | @property (nonatomic, copy) CGFloat(^customHeightBlock)(CellType cell, NSIndexPath *indexPath); 30 | @property (nonatomic, copy) BOOL(^hiddenBlock)(NSIndexPath *indexPath); 31 | 32 | /// 为指定的索引设置是否隐藏 33 | /// @param hidden 是否隐藏 34 | /// @param indexPath 指定索引 35 | - (void)setHidden:(BOOL)hidden 36 | indexPath:(NSIndexPath *)indexPath; 37 | 38 | /// 获取指定的索引已经显示内容是否隐藏 如果不存在默认位显示 39 | /// @param indexPath 指定的索引 40 | - (BOOL)isHiddenDisplayWithIndexPath:(NSIndexPath *)indexPath; 41 | 42 | /// 获取最新当前索引是否隐藏 43 | /// @param indexPath 指定索引 44 | - (BOOL)isHiddenWithIndexPath:(NSIndexPath *)indexPath; 45 | /** 46 | * 为了是支持泛型 47 | 48 | @param configCompletionHandle 设置的Block 49 | */ 50 | - (void)setConfigCompletionHandle:(void (^)(CellType cell, NSIndexPath * indexPath))configCompletionHandle; 51 | 52 | /** 53 | * 为了支持泛型 54 | 55 | @param didSelectRowCompletionHandle 点击回调的block 56 | */ 57 | - (void)setDidSelectRowCompletionHandle:(void (^)(CellType cell, NSIndexPath * indexPath))didSelectRowCompletionHandle; 58 | 59 | /** 60 | 点击所在的 Cell 的执行方法 61 | 62 | @param cell 点击的 Cell 63 | @param indexPath 点击 cell 所在的索引 64 | */ 65 | - (void)didSelectRowAtWithCell:(CellType)cell 66 | indexPath:(NSIndexPath *)indexPath; 67 | 68 | /** 69 | 配置 Cell 的执行方法 70 | 71 | @param cell 配置的 Cell 72 | @param indexPath 配置 Cell 所在的索引 73 | */ 74 | - (void)configCellWithCell:(CellType)cell 75 | indexPath:(NSIndexPath *)indexPath; 76 | 77 | /** 78 | 一个方法配置所有的参数 79 | 80 | @param cellNumber cell 的数量 81 | @param identifier 标识符 82 | @param anyClass cell 的类名 83 | @param height 高度 84 | @param configCompletionHandle 配置 cell 85 | @param didSelectRowCompletionHandle 点击 cell 方法 86 | */ 87 | - (void)configurationCellWithCellNumber:(NSUInteger)cellNumber 88 | identifier:(NSString *)identifier 89 | anyClass:(Class)anyClass 90 | height:(CGFloat)height 91 | configCompletionHandle:(void(^)(CellType cell, NSIndexPath *indexPath))configCompletionHandle 92 | didSelectRowCompletionHandle:(void(^)(CellType cell, NSIndexPath *indexPath))didSelectRowCompletionHandle; 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewCell.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/3/18. 6 | // 7 | // 8 | 9 | #import "ZHTableViewCell.h" 10 | 11 | @implementation ZHTableViewCell { 12 | NSMutableDictionary *_hiddenMap; 13 | } 14 | 15 | - (instancetype)init { 16 | if (self = [super init]) { 17 | _cellNumber = 1; 18 | _hiddenMap = [NSMutableDictionary dictionary]; 19 | } 20 | return self; 21 | } 22 | 23 | - (void)setConfigCompletionHandle:(void (^)(UITableViewCell *, NSIndexPath *))configCompletionHandle { 24 | _configCompletionHandle = configCompletionHandle; 25 | } 26 | 27 | - (void)setDidSelectRowCompletionHandle:(void (^)(UITableViewCell *, NSIndexPath *))didSelectRowCompletionHandle { 28 | _didSelectRowCompletionHandle = didSelectRowCompletionHandle; 29 | } 30 | 31 | - (void)didSelectRowAtWithCell:(UITableViewCell *)cell 32 | indexPath:(NSIndexPath *)indexPath { 33 | if (!self.didSelectRowCompletionHandle) { 34 | return; 35 | } 36 | self.didSelectRowCompletionHandle(cell,indexPath); 37 | } 38 | 39 | - (void)configCellWithCell:(UITableViewCell *)cell 40 | indexPath:(NSIndexPath *)indexPath { 41 | if (!self.configCompletionHandle) { 42 | return; 43 | } 44 | self.configCompletionHandle(cell,indexPath); 45 | } 46 | 47 | - (void)configurationCellWithCellNumber:(NSUInteger)cellNumber identifier:(NSString *)identifier anyClass:(Class)anyClass height:(CGFloat)height configCompletionHandle:(void (^)(UITableViewCell *, NSIndexPath *))configCompletionHandle didSelectRowCompletionHandle:(void (^)(UITableViewCell *, NSIndexPath *))didSelectRowCompletionHandle { 48 | self.cellNumber = cellNumber; 49 | self.identifier = identifier; 50 | self.anyClass = anyClass; 51 | self.height = height; 52 | self.configCompletionHandle = configCompletionHandle; 53 | self.didSelectRowCompletionHandle = didSelectRowCompletionHandle; 54 | } 55 | 56 | - (void)setHidden:(BOOL)hidden 57 | indexPath:(NSIndexPath *)indexPath { 58 | NSString *key = [self hiddenKeyWithIndexPath:indexPath]; 59 | _hiddenMap[key] = @(hidden); 60 | } 61 | 62 | - (BOOL)isHiddenDisplayWithIndexPath:(NSIndexPath *)indexPath { 63 | NSString *key = [self hiddenKeyWithIndexPath:indexPath]; 64 | NSNumber *hiddenNumber = _hiddenMap[key]; 65 | if (!hiddenNumber) { 66 | return NO; 67 | } 68 | return [hiddenNumber boolValue]; 69 | } 70 | 71 | - (BOOL)isHiddenWithIndexPath:(NSIndexPath *)indexPath { 72 | BOOL isHidden = self.hiddenBlock && self.hiddenBlock(indexPath); 73 | return isHidden; 74 | } 75 | 76 | - (NSString *)hiddenKeyWithIndexPath:(NSIndexPath *)indexPath { 77 | return [NSString stringWithFormat:@"hidden-%@-%@",@(indexPath.section),@(indexPath.row)]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewDataSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewDataSource.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/3/18. 6 | // 7 | // 8 | 9 | #import 10 | #import "ZHTableViewGroup.h" 11 | #import "ZHAutoConfigurationTableViewDelegate.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | /** 15 | 添加分组的回调 16 | 17 | @param group 创建的分组对象 18 | */ 19 | typedef void(^ZHTableViewDataSourceAddGroupCompletionHandle)(ZHTableViewGroup * group); 20 | 21 | /** 22 | 自定义高度的回调 23 | 24 | @return 自定义算法返回的高度 25 | */ 26 | typedef CGFloat (^ZHTableViewDataSourceCustomHeightCompletionHandle)(ZHTableViewBaseModel * model); 27 | 28 | /** 29 | 进行 UITableView 进行数据托管的数据源 30 | */ 31 | @interface ZHTableViewDataSource : NSObject 32 | 33 | /** 34 | 自动配置 UITableView 的 DataSource 和 Delegate 默认为 YES 35 | */ 36 | @property (nonatomic, assign, getter=isAutoConfigurationTableViewDelegate) BOOL autoConfigurationTableViewDelegate; 37 | 38 | /** 39 | * 是否开启即将展示 复制数据 默认为 NO 40 | */ 41 | @property (nonatomic, assign) BOOL isWillDisplayData; 42 | /** 43 | 添加优先级 如果 YES 启用新的优先级 先判断设置的高度 没有获取自定义 Block 的高度 其次是自动计算高度 44 | */ 45 | @property (nonatomic, assign) BOOL priorityHeight; 46 | 47 | @property (nonatomic, strong, readonly) NSMutableArray * groups; 48 | /// 设置ZHAutoConfigurationTableViewDelegate子类的代理 49 | @property (nonatomic, strong) ZHAutoConfigurationTableViewDelegate *tableViewDelegate; 50 | @property (nonatomic, weak) UITableView *tableView; 51 | /** 52 | 唯一的初始化ZHTableViewDataSource 53 | 54 | @param tableView 托管的 UITableView 的对象 必须存在 55 | @return ZHTableViewDataSource的对象 56 | */ 57 | - (instancetype)initWithTableView:(UITableView *)tableView; 58 | 59 | /** 60 | 添加一个分组 61 | 62 | @param completionHandle 返回新注册的分组对象 可以进行配置 63 | */ 64 | - (ZHTableViewGroup *)addGroupWithCompletionHandle:(ZHTableViewDataSourceAddGroupCompletionHandle)completionHandle; 65 | 66 | /// 注册所有的Cell 67 | - (void)registerClass; 68 | 69 | /** 70 | 进行刷新 UITableView 71 | */ 72 | - (void)reloadTableViewData; 73 | 74 | /** 75 | 获取分组Cell的个数 如果autoConfigurationTableViewDelegate = YES 此方法不用调用 76 | 77 | @param dataSource ZHTableViewDataSource数据源 78 | @param section 所在组索引 79 | @return 分组 Cell 的个数 80 | */ 81 | + (NSInteger)numberOfRowsInSectionWithDataSource:(ZHTableViewDataSource *)dataSource section:(NSInteger)section; 82 | 83 | /** 84 | 获取对应索引的UITableViewCell 如果autoConfigurationTableViewDelegate = YES 此方法不用调用 85 | 86 | @param dataSource ZHTableViewDataSource数据源 87 | @param indexPath 所在的索引 88 | @return UITableViewCell 89 | */ 90 | + (UITableViewCell *)cellForRowAtWithDataSource:(ZHTableViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath; 91 | 92 | /** 93 | 获取分组的个数 如果autoConfigurationTableViewDelegate = YES 此方法不用调用 94 | 95 | @param dataSource ZHTableViewDataSource的数据源 96 | @return 分组的个数 97 | */ 98 | + (NSInteger)numberOfSectionsWithDataSource:(ZHTableViewDataSource *)dataSource; 99 | 100 | /** 101 | 获取Cell 所在索引的高度 如果autoConfigurationTableViewDelegate = YES 此方法不用调用 102 | 103 | @param dataSource ZHTableViewDataSource数据源 104 | @param indexPath 索引 105 | @param customHeightCompletionHandle 自定义高度回调 实现 ZHTableViewCell 属性 cellHeight 无效 106 | @return Cell 的高度 107 | */ 108 | + (CGFloat)heightForRowAtDataSource:(ZHTableViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath customHeightCompletionHandle:(ZHTableViewDataSourceCustomHeightCompletionHandle)customHeightCompletionHandle; 109 | 110 | /** 111 | 点击 Cell 的回调 112 | 113 | @param dataSource ZHTableViewDataSource数据源 114 | @param indexPath 点击的索引 115 | */ 116 | + (void)didSelectRowAtWithDataSource:(ZHTableViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath; 117 | 118 | /** 119 | 获取 Header 的高度 120 | 121 | @param dataSource ZHTableViewDataSource数据源 122 | @param section 分组索引 123 | @param customHeightCompletionHandle 自定义高度回调 124 | @return 分组 Header 高度 125 | */ 126 | + (CGFloat)heightForHeaderInSectionWithDataSource:(ZHTableViewDataSource *)dataSource section:(NSInteger)section customHeightCompletionHandle:(ZHTableViewDataSourceCustomHeightCompletionHandle)customHeightCompletionHandle; 127 | 128 | /** 129 | 获取 Footer 的高度 130 | 131 | @param dataSource ZHTableViewDataSource数据源 132 | @param section 分组索引 133 | @param customHeightCompletionHandle 自定义高度回调 134 | @return 分组 Footer 高度 135 | */ 136 | + (CGFloat)heightForFooterInSectionWithDataSource:(ZHTableViewDataSource *)dataSource section:(NSInteger)section customHeightCompletionHandle:(ZHTableViewDataSourceCustomHeightCompletionHandle)customHeightCompletionHandle; 137 | 138 | /** 139 | 获取Header 140 | 141 | @param dataSource ZHTableViewDataSource数据源 142 | @param section 分组的索引 143 | @return 分组 Header 试图 144 | */ 145 | + (UITableViewHeaderFooterView *)viewForHeaderInSectionWithDataSource:(ZHTableViewDataSource *)dataSource section:(NSInteger)section; 146 | /** 147 | 获取Footer 148 | 149 | @param dataSource ZHTableViewDataSource数据源 150 | @param section 分组的索引 151 | @return 分组 Footer 试图 152 | */ 153 | + (UITableViewHeaderFooterView *)viewForFooterInSectionWithDataSource:(ZHTableViewDataSource *)dataSource section:(NSInteger)section; 154 | 155 | /** 156 | 清空之前数据 157 | */ 158 | - (void)clearData; 159 | 160 | + (NSIndexPath *)indexPathWithDataSource:(ZHTableViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath; 161 | 162 | + (void)dataSource:(ZHTableViewDataSource *)dataSource willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath; 163 | 164 | @property (nonatomic, copy) void (^heightForRowAtIndexPath)(UITableView *tableView, NSIndexPath *indexPath, CGFloat height); 165 | @property (nonatomic, copy) void (^heightForHeaderInSection)(UITableView *tableView, NSUInteger section, CGFloat height); 166 | @property (nonatomic, copy) void (^heightForFooterInSection)(UITableView *tableView, NSUInteger section, CGFloat height); 167 | #pragma mark - Delegate Block 168 | /* UITableView 滑动, scrollViewDidScroll的代理 */ 169 | @property (nonatomic, copy) void (^scrollViewDidScrollCompletionHandle)(UIScrollView *scrollView); 170 | /* UITableView 滑动,scrollViewWillBeginDragging的代理 */ 171 | @property (nonatomic, copy) void (^scrollViewWillBeginDraggingCompletionHandle)(UIScrollView *scrollView); 172 | @property (nonatomic, copy) void (^scrollViewDidZoom)(UIScrollView *scrollView); 173 | @property (nonatomic, copy) void (^scrollViewWillEndDragging)(UIScrollView *scrollView, CGPoint velocity, CGPoint *targetContentOffset); 174 | @property (nonatomic, copy) void (^scrollViewDidEndDragging)(UIScrollView *scrollView, BOOL decelerate); 175 | @property (nonatomic, copy) void (^scrollViewWillBeginDecelerating)(UIScrollView *scrollView); 176 | @property (nonatomic, copy) void (^scrollViewDidEndDecelerating)(UIScrollView *scrollView); 177 | @property (nonatomic, copy) void (^scrollViewDidEndScrollingAnimation)(UIScrollView *scrollView); 178 | @property (nonatomic, copy) UIView *__nullable (^viewForZoomingInScrollView)(UIScrollView *scrollView); 179 | @property (nonatomic, copy) void (^scrollViewWillBeginZooming)(UIScrollView *scrollView, UIView *view); 180 | @property (nonatomic, copy) void (^scrollViewDidEndZooming)(UIScrollView *scrollView, UIView *view, CGFloat scale); 181 | @property (nonatomic, copy) BOOL (^scrollViewShouldScrollToTop)(UIScrollView *scrollView); 182 | @property (nonatomic, copy) void (^scrollViewDidScrollToTop)(UIScrollView *scrollView); 183 | @property (nonatomic, copy) void (^scrollViewDidChangeAdjustedContentInset)(UIScrollView *scrollView); 184 | 185 | 186 | @end 187 | 188 | @interface ZHTableViewDataSource (ReloadHeight) 189 | 190 | /// 根据标识符刷新自动计算高度 191 | /// @param identifier 标识符 192 | - (void)reloadCellAutomaticHeightWithIdentifier:(NSString *)identifier; 193 | /// 根据标识符刷新固定高度 194 | /// @param height 固定高度 195 | /// @param identifier 标识符 196 | - (void)reloadCellFixedHeight:(CGFloat)height 197 | identifier:(NSString *)identifier; 198 | 199 | /// 根据类类型刷新自动计算高度 200 | /// @param className 类类型 201 | - (void)reloadCellAutomaticHeightWithClass:(Class)className; 202 | /// 根据类类型刷新固定高度 203 | /// @param height 固定高度 204 | /// @param className 类类型 205 | - (void)reloadCellFixedHeight:(CGFloat)height 206 | className:(Class)className; 207 | 208 | /// 根据指定的`ZHTableViewCell`刷新自动计算高度 209 | /// @param tableViewCell 指定的`ZHTableViewCell` 210 | - (void)reloadCellAutomaticHeightWithTableViewCell:(ZHTableViewCell *)tableViewCell; 211 | /// 根据指定的`ZHTableViewCell`刷新固定高度 212 | /// @param height 固定的高度 213 | /// @param tableViewCell 指定的`ZHTableViewCell` 214 | - (void)reloadCellFixedHeight:(NSInteger)height 215 | tableViewCell:(ZHTableViewCell *)tableViewCell; 216 | 217 | /// 根据对应分组个对应的`ZHTableViewCell`索引更新自动高度 218 | /// @param groupIndex 分组的索引 219 | /// @param cellIndex 对应的`ZHTableViewCell`索引 220 | - (void)reloadCellAutomicHeightWithGroupIndex:(NSUInteger)groupIndex 221 | cellIndex:(NSUInteger)cellIndex; 222 | /// 根据对应分组个对应的`ZHTableViewCell`索引更新固定高度 223 | /// @param height 固定高度 224 | /// @param groupIndex 分组的索引 225 | /// @param cellIndex 对应的`ZHTableViewCell`索引 226 | - (void)reloadCellFixedHeight:(CGFloat)height 227 | groupIndex:(NSUInteger)groupIndex 228 | cellIndex:(NSUInteger)cellIndex; 229 | 230 | @end 231 | 232 | 233 | @interface ZHTableViewDataSource (ReloadCell) 234 | 235 | /// 通过标识符刷新对应的ZHTableViewCell 236 | /// @param identienfier 标识符 237 | - (void)reloadCellWithIdentifier:(NSString *)identienfier; 238 | /// 通过指定Class类型刷新对应的ZHTableViewCell 239 | /// @param className Class类型 240 | - (void)reloadCellWithClassName:(Class)className; 241 | /// 通过指定的ZHTableViewCell刷新ZHTableViewCell 242 | /// @param tableViewCell 指定ZHTableViewCell对象 243 | - (void)reloadCellWithTableViewCell:(ZHTableViewCell *)tableViewCell; 244 | /// 通过指定索引刷新ZHTableViewCell 245 | /// @param groupIndex 对应分组索引 246 | /// @param cellIndex 对应ZHTableViewCell索引 247 | - (void)reloadCellWithGroupIndex:(NSUInteger)groupIndex 248 | cellIndex:(NSUInteger)cellIndex; 249 | 250 | - (NSMutableArray *)indexPathsWithTableViewCell:(ZHTableViewCell *)tableViewCell; 251 | 252 | @end 253 | 254 | @interface ZHTableViewDataSource (ReloadData) 255 | 256 | /// 根据标识符更新数据 257 | /// @param dataCount 数据的总数 258 | /// @param identifier 标识符 259 | - (void)reloadCellWithDataCount:(NSUInteger)dataCount 260 | identifier:(NSString *)identifier; 261 | /// 根据Class类型更新数据 262 | /// @param dataCount 数据的总数 263 | /// @param className Class的类型 264 | - (void)reloadCellWithDataCount:(NSUInteger)dataCount 265 | className:(Class)className; 266 | /// 根据指定ZHTableViewCell更新数据 267 | /// @param dataCount 数据的总数 268 | /// @param tableViewCell 指定的ZHTableViewCell 269 | - (void)reloadCellWithDataCount:(NSUInteger)dataCount 270 | tableViewCell:(ZHTableViewCell *)tableViewCell; 271 | /// 根据指定的索引更新数据 272 | /// @param dataCount 数据的总数 273 | /// @param groupIndex 分组的索引 274 | /// @param cellIndex ZHTableViewCell的索引 275 | - (void)reloadCellWithDataCount:(NSUInteger)dataCount 276 | groupIndex:(NSUInteger)groupIndex 277 | cellIndex:(NSUInteger)cellIndex; 278 | 279 | - (void)updatesTableView:(void(^)(void))update; 280 | 281 | @end 282 | 283 | @interface ZHTableViewDataSource (Cell) 284 | 285 | /// 根据条件过滤ZHTableViewCell 286 | /// @param config 过滤的条件 287 | - (NSArray *)filterCellWithConfig:(BOOL (^)(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell))config; 288 | 289 | /// 根据tableViewCell找到对应在UITableView所在的索引 290 | /// @param tableViewCell 对应的tableViewCell 291 | - (NSIndexPath *)indexPathWithTableViewCell:(ZHTableViewCell *)tableViewCell; 292 | 293 | @end 294 | 295 | @interface ZHTableViewDataSource (Hidden) 296 | 297 | /// 刷新当前所有隐藏的Cell 298 | - (void)reloadAllHiddenCell; 299 | 300 | @end 301 | 302 | NS_ASSUME_NONNULL_END 303 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewDataSource.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewDataSource.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/3/18. 6 | // 7 | // 8 | 9 | #import "ZHTableViewDataSource.h" 10 | #import "ZHAutoConfigurationTableViewDelegate.h" 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ZHTableViewDataSource () 14 | 15 | @property (nonatomic, strong) NSMutableArray *groups; 16 | 17 | @end 18 | 19 | @implementation ZHTableViewDataSource { 20 | NSCache *_cellCache; 21 | } 22 | 23 | - (instancetype)initWithTableView:(UITableView *)tableView { 24 | if (self = [super init]) { 25 | _tableView = tableView; 26 | _autoConfigurationTableViewDelegate = YES; 27 | _cellCache = [[NSCache alloc] init]; 28 | } 29 | return self; 30 | } 31 | 32 | - (ZHTableViewGroup *)addGroupWithCompletionHandle:(ZHTableViewDataSourceAddGroupCompletionHandle)completionHandle { 33 | ZHTableViewGroup *group = [[ZHTableViewGroup alloc] init]; 34 | if (completionHandle) { 35 | completionHandle(group); 36 | } 37 | [self.groups addObject:group]; 38 | return group; 39 | } 40 | 41 | - (void)reloadTableViewData { 42 | if (!self.tableView.dataSource) { 43 | if (self.isAutoConfigurationTableViewDelegate) { 44 | self.tableView.dataSource = self.tableViewDelegate; 45 | } else { 46 | NSAssert(NO, @"必须给 UITableView 设置 DataSource 代理"); 47 | } 48 | } 49 | if (!self.tableView.delegate) { 50 | if (self.isAutoConfigurationTableViewDelegate) { 51 | self.tableView.delegate = self.tableViewDelegate; 52 | } 53 | } 54 | [self registerClass]; 55 | [self.tableView reloadData]; 56 | } 57 | 58 | + (NSInteger)numberOfRowsInSectionWithDataSource:(ZHTableViewDataSource *)dataSource 59 | section:(NSInteger)section { 60 | ZHTableViewGroup *group = [self groupForSectionWithDataSource:dataSource section:section]; 61 | if (!group) { 62 | return 0; 63 | } 64 | return group.cellCount; 65 | } 66 | 67 | + (UITableViewCell *)cellForRowAtWithDataSource:(ZHTableViewDataSource *)dataSource 68 | indexPath:(NSIndexPath *)indexPath { 69 | return [self cellForRowAtWithDataSource:dataSource 70 | indexPath:indexPath 71 | config:!dataSource.isWillDisplayData]; 72 | } 73 | 74 | + (UITableViewCell *)cellForRowAtWithDataSource:(ZHTableViewDataSource *)dataSource 75 | indexPath:(NSIndexPath *)indexPath 76 | config:(BOOL)config 77 | useCache:(BOOL)useCache { 78 | ZHTableViewGroup *group = [self groupForSectionWithDataSource:dataSource section:indexPath.section]; 79 | ZHTableViewCell *tableViewCell = [group tableViewCellForIndexPath:indexPath]; 80 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; 81 | if (!group) { 82 | return cell; 83 | } 84 | UITableViewCell *resultCell; 85 | if (useCache) { 86 | UITableViewCell *cacheCell = [dataSource cacheCellWithIndexPath:indexPath]; 87 | if ([cacheCell isKindOfClass:tableViewCell.anyClass]) { 88 | resultCell = [dataSource cacheCellWithIndexPath:indexPath]; 89 | [group tableViewCell:tableViewCell configCell:resultCell atIndexPath:indexPath]; 90 | } 91 | } 92 | if (!resultCell) { 93 | resultCell = [group cellForTableViewWithTableView:dataSource.tableView 94 | indexPath:indexPath 95 | config:config]; 96 | } 97 | if (!resultCell) { 98 | return cell; 99 | } 100 | NSIndexPath *realIndexPath = [group indexPathWithCell:tableViewCell indexPath:indexPath]; 101 | BOOL isHidden = [tableViewCell isHiddenWithIndexPath:realIndexPath]; 102 | resultCell.hidden = isHidden; 103 | if (!useCache) { 104 | [dataSource saveCacheWithCell:resultCell indexPath:indexPath]; 105 | } 106 | return resultCell; 107 | } 108 | 109 | - (UITableViewCell *)cacheCellWithIndexPath:(NSIndexPath *)indexPath { 110 | return [_cellCache objectForKey:[self cacheKeyWithIndexPath:indexPath]]; 111 | } 112 | 113 | - (void)saveCacheWithCell:(UITableViewCell *)cell indexPath:(NSIndexPath *)indexPath { 114 | [_cellCache setObject:cell forKey:[self cacheKeyWithIndexPath:indexPath]]; 115 | } 116 | 117 | - (NSString *)cacheKeyWithIndexPath:(NSIndexPath *)indexPath { 118 | return [NSString stringWithFormat:@"%@-%@",@(indexPath.section),@(indexPath.row)]; 119 | } 120 | 121 | + (UITableViewCell *)cellForRowAtWithDataSource:(ZHTableViewDataSource *)dataSource 122 | indexPath:(NSIndexPath *)indexPath 123 | config:(BOOL)config { 124 | return [self cellForRowAtWithDataSource:dataSource 125 | indexPath:indexPath 126 | config:config 127 | useCache:NO]; 128 | } 129 | 130 | + (NSInteger)numberOfSectionsWithDataSource:(ZHTableViewDataSource *)dataSource { 131 | if (!dataSource) { 132 | return 0; 133 | } 134 | return dataSource.groups.count; 135 | } 136 | 137 | + (CGFloat)heightForRowAtDataSource:(ZHTableViewDataSource *)dataSource 138 | indexPath:(NSIndexPath *)indexPath customHeightCompletionHandle:(ZHTableViewDataSourceCustomHeightCompletionHandle)customHeightCompletionHandle { 139 | ZHTableViewCell *cell = [self cellForIndexPath:dataSource indexPath:indexPath]; 140 | 141 | if (!cell) { 142 | return 0; 143 | } 144 | NSIndexPath *realyIndexPath = [self indexPathWithDataSource:dataSource 145 | indexPath:indexPath]; 146 | if ([cell isHiddenWithIndexPath:realyIndexPath]) { 147 | return 0; 148 | } 149 | if (cell.customHeightBlock) { 150 | UITableViewCell *tableViewCell = [self cellForRowAtWithDataSource:dataSource 151 | indexPath:indexPath 152 | config:YES 153 | useCache:YES]; 154 | return cell.customHeightBlock(tableViewCell, realyIndexPath); 155 | } 156 | if (!dataSource.priorityHeight) { 157 | CGFloat automaticHeight = ({ 158 | automaticHeight = CGFLOAT_MAX; 159 | if (cell.height == NSNotFound) { 160 | UITableViewCell *automaticHeightCell = [self cellForRowAtWithDataSource:dataSource indexPath:indexPath config:YES 161 | useCache:YES]; 162 | automaticHeight = [automaticHeightCell sizeThatFits:CGSizeMake([UIScreen mainScreen].bounds.size.width, CGFLOAT_MAX)].height; 163 | } 164 | automaticHeight; 165 | }); 166 | CGFloat height = cell.height; 167 | if (cell.height == NSNotFound && automaticHeight != CGFLOAT_MAX) { 168 | height = automaticHeight; 169 | } 170 | return [self heightWithCustomHandle:height 171 | customCompletionHandle:customHeightCompletionHandle 172 | baseModel:cell]; 173 | } else { 174 | CGFloat heigh = cell.height; 175 | if (heigh > 0 && heigh < CGFLOAT_MAX && heigh < NSNotFound) { 176 | return heigh; 177 | } 178 | if (customHeightCompletionHandle) { 179 | heigh = customHeightCompletionHandle(cell); 180 | if (heigh > 0 && heigh < CGFLOAT_MAX && heigh < NSNotFound) { 181 | return heigh; 182 | } 183 | } 184 | CGFloat automaticHeight = ({ 185 | automaticHeight = CGFLOAT_MAX; 186 | if (cell.height == NSNotFound) { 187 | UITableViewCell *automaticHeightCell = [self cellForRowAtWithDataSource:dataSource 188 | indexPath:indexPath 189 | config:YES 190 | useCache:YES]; 191 | automaticHeight = [automaticHeightCell sizeThatFits:CGSizeMake([UIScreen mainScreen].bounds.size.width, CGFLOAT_MAX)].height; 192 | } 193 | automaticHeight; 194 | }); 195 | return automaticHeight; 196 | } 197 | } 198 | 199 | + (void)didSelectRowAtWithDataSource:(ZHTableViewDataSource *)dataSource 200 | indexPath:(NSIndexPath *)indexPath { 201 | 202 | ZHTableViewCell *tableViewCell = [self cellForIndexPath:dataSource indexPath:indexPath]; 203 | if (!tableViewCell) { 204 | return; 205 | } 206 | __block UITableViewCell *cell = ({ 207 | cell = nil; 208 | /* 因为点击的 CELL 一定是在屏幕可见的范围之内 所以直接取 */ 209 | [dataSource.tableView.visibleCells enumerateObjectsUsingBlock:^(__kindof UITableViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 210 | NSIndexPath *visibleIndexPath = [dataSource.tableView indexPathForCell:obj]; 211 | if ([indexPath compare:visibleIndexPath] == NSOrderedSame) { 212 | cell = obj; 213 | } 214 | }]; 215 | cell; 216 | }); 217 | if (!cell) { 218 | return; 219 | } 220 | ZHTableViewGroup *group = [self groupForSectionWithDataSource:dataSource section:indexPath.section]; 221 | [tableViewCell didSelectRowAtWithCell:cell indexPath:[group indexPathWithCell:tableViewCell indexPath:indexPath]]; 222 | } 223 | 224 | + (CGFloat)heightForHeaderInSectionWithDataSource:(ZHTableViewDataSource *)dataSource 225 | section:(NSInteger)section customHeightCompletionHandle:(ZHTableViewDataSourceCustomHeightCompletionHandle)customHeightCompletionHandle { 226 | return [self heightForHeaderFooterInSectionWithDataSource:dataSource section:section style:ZHTableViewHeaderFooterStyleHeader customHeightCompletionHandle:customHeightCompletionHandle]; 227 | } 228 | 229 | + (CGFloat)heightForFooterInSectionWithDataSource:(ZHTableViewDataSource *)dataSource 230 | section:(NSInteger)section customHeightCompletionHandle:(ZHTableViewDataSourceCustomHeightCompletionHandle)customHeightCompletionHandle { 231 | return [self heightForHeaderFooterInSectionWithDataSource:dataSource section:section style:ZHTableViewHeaderFooterStyleFooter customHeightCompletionHandle:customHeightCompletionHandle]; 232 | } 233 | 234 | + (UITableViewHeaderFooterView *)viewForHeaderInSectionWithDataSource:(ZHTableViewDataSource *)dataSource 235 | section:(NSInteger)section { 236 | return [self viewHeaderFooterInSectionWithDtaSource:dataSource section:section style:ZHTableViewHeaderFooterStyleHeader]; 237 | } 238 | 239 | + (UITableViewHeaderFooterView *)viewForFooterInSectionWithDataSource:(ZHTableViewDataSource *)dataSource 240 | section:(NSInteger)section { 241 | return [self viewHeaderFooterInSectionWithDtaSource:dataSource section:section style:ZHTableViewHeaderFooterStyleFooter]; 242 | } 243 | 244 | - (void)clearData { 245 | [self.groups removeAllObjects]; 246 | [_cellCache removeAllObjects]; 247 | } 248 | 249 | + (UITableViewHeaderFooterView *)viewHeaderFooterInSectionWithDtaSource:(ZHTableViewDataSource *)dataSource 250 | section:(NSInteger)section style:(ZHTableViewHeaderFooterStyle)style { 251 | ZHTableViewGroup *group = [self groupForSectionWithDataSource:dataSource section:section]; 252 | if (!group) { 253 | return nil; 254 | } 255 | return [group headerFooterForStyle:style tableView:dataSource.tableView section:section]; 256 | } 257 | 258 | + (CGFloat)heightForHeaderFooterInSectionWithDataSource:(ZHTableViewDataSource *)dataSource 259 | section:(NSInteger)section style:(ZHTableViewHeaderFooterStyle)style 260 | customHeightCompletionHandle:(ZHTableViewDataSourceCustomHeightCompletionHandle)customHeightCompletionHandle { 261 | ZHTableViewGroup *group = [self groupForSectionWithDataSource:dataSource section:section]; 262 | if(!group) { 263 | return 0; 264 | } 265 | NSInteger height = 0; 266 | ZHTableViewBaseModel *baseModel; 267 | UITableViewHeaderFooterView *headFooter = [self viewHeaderFooterInSectionWithDtaSource:dataSource section:section style:style]; 268 | CGFloat automaticHeight = [headFooter sizeThatFits:CGSizeMake([UIScreen mainScreen].bounds.size.width, CGFLOAT_MAX)].height; 269 | switch (style) { 270 | case ZHTableViewHeaderFooterStyleHeader: { 271 | height = group.header.height; 272 | baseModel = group.header; 273 | if (group.header.customHeightBlock) { 274 | [group.header setHeaderFooter:headFooter section:section]; 275 | return group.header.customHeightBlock(headFooter,section); 276 | } 277 | } 278 | break; 279 | case ZHTableViewHeaderFooterStyleFooter: { 280 | height = group.footer.height; 281 | baseModel = group.footer; 282 | if (group.footer.customHeightBlock) { 283 | [group.footer setHeaderFooter:headFooter section:section]; 284 | return group.footer.customHeightBlock(headFooter,section); 285 | } 286 | } 287 | break; 288 | } 289 | if (height == NSNotFound && automaticHeight != CGFLOAT_MAX) { 290 | height = automaticHeight; 291 | } 292 | return [self heightWithCustomHandle:height customCompletionHandle:customHeightCompletionHandle baseModel:baseModel]; 293 | } 294 | 295 | + (CGFloat)heightWithCustomHandle:(CGFloat)height 296 | customCompletionHandle:(ZHTableViewDataSourceCustomHeightCompletionHandle)customCompletionHandle 297 | baseModel:(ZHTableViewBaseModel *)baseModel { 298 | return [self lookBestHeightWithBlock:^CGFloat(NSUInteger index, BOOL *stop) { 299 | if (index == 0) { 300 | return height; 301 | } else if (index == 1 && customCompletionHandle) { 302 | return customCompletionHandle(baseModel); 303 | } else { 304 | *stop = YES; 305 | return 0; 306 | } 307 | }]; 308 | } 309 | 310 | + (BOOL)isVirifyHeight:(CGFloat)height { 311 | return height != NSNotFound && height != CGFLOAT_MAX; 312 | } 313 | 314 | + (CGFloat)lookBestHeightWithBlock:(CGFloat(^)(NSUInteger index, BOOL *stop))block { 315 | CGFloat height = 0; 316 | BOOL stop = NO; 317 | NSUInteger index = 0; 318 | while (!stop) { 319 | height = block(index, &stop); 320 | if ([self isVirifyHeight:height]) { 321 | return height; 322 | } 323 | index ++; 324 | } 325 | return height; 326 | } 327 | 328 | + (ZHTableViewGroup *)groupForSectionWithDataSource:(ZHTableViewDataSource *)dataSource 329 | section:(NSInteger)section { 330 | if (!dataSource) { 331 | return nil; 332 | } 333 | if (dataSource.groups.count <= section) { 334 | return nil; 335 | } 336 | return dataSource.groups[section]; 337 | } 338 | 339 | + (ZHTableViewCell *)cellForIndexPath:(ZHTableViewDataSource *)dataSource 340 | indexPath:(NSIndexPath *)indexPath { 341 | ZHTableViewGroup *group = [self groupForSectionWithDataSource:dataSource section:indexPath.section]; 342 | if (!group) { 343 | return nil; 344 | } 345 | return [group tableViewCellForIndexPath:indexPath]; 346 | } 347 | 348 | + (NSIndexPath *)indexPathWithDataSource:(ZHTableViewDataSource *)dataSource indexPath:(NSIndexPath *)indexPath { 349 | ZHTableViewGroup *group = [self groupForSectionWithDataSource:dataSource section:indexPath.section]; 350 | ZHTableViewCell *tableViewCell = [self cellForIndexPath:dataSource indexPath:indexPath]; 351 | return [group indexPathWithCell:tableViewCell indexPath:indexPath]; 352 | } 353 | 354 | + (void)dataSource:(ZHTableViewDataSource *)dataSource 355 | willDisplayCell:(UITableViewCell *)cell 356 | forRowAtIndexPath:(NSIndexPath *)indexPath { 357 | if (!dataSource.isWillDisplayData) { 358 | return; 359 | } 360 | ZHTableViewGroup *group = [self groupForSectionWithDataSource:dataSource 361 | section:indexPath.section]; 362 | ZHTableViewCell *tableViewCell = [self cellForIndexPath:dataSource 363 | indexPath:indexPath]; 364 | [group tableViewCell:tableViewCell 365 | configCell:cell 366 | atIndexPath:indexPath]; 367 | } 368 | 369 | - (void)registerClass { 370 | for (ZHTableViewGroup *group in self.groups) { 371 | [group registerHeaderFooterCellWithTableView:self.tableView]; 372 | } 373 | } 374 | 375 | - (NSMutableArray *)groups { 376 | if (!_groups) { 377 | _groups = [NSMutableArray array]; 378 | } 379 | return _groups; 380 | } 381 | 382 | - (ZHAutoConfigurationTableViewDelegate *)tableViewDelegate { 383 | if (!_tableViewDelegate) { 384 | _tableViewDelegate = [[ZHAutoConfigurationTableViewDelegate alloc] initWithDataSource:self]; 385 | } 386 | return _tableViewDelegate; 387 | } 388 | 389 | @end 390 | 391 | @implementation ZHTableViewDataSource (ReloadHeight) 392 | 393 | #pragma mark - 根据标识符刷新高度 394 | - (void)reloadCellAutomaticHeightWithIdentifier:(NSString *)identifier { 395 | [self reloadCellFixedHeight:NSNotFound 396 | identifier:identifier]; 397 | } 398 | 399 | - (void)reloadCellFixedHeight:(CGFloat)height 400 | identifier:(NSString *)identifier { 401 | [self reloadCellHeight:height 402 | tableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell) { 403 | return [tableViewCell.identifier isEqualToString:identifier]; 404 | }]; 405 | } 406 | 407 | #pragma mark - 根据类类型刷新高度 408 | - (void)reloadCellAutomaticHeightWithClass:(Class)className { 409 | [self reloadCellFixedHeight:NSNotFound 410 | className:className]; 411 | } 412 | 413 | - (void)reloadCellFixedHeight:(CGFloat)height 414 | className:(Class)className { 415 | [self reloadCellHeight:height 416 | tableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell) { 417 | return tableViewCell.anyClass == className; 418 | }]; 419 | } 420 | 421 | - (void)reloadCellAutomaticHeightWithTableViewCell:(ZHTableViewCell *)tableViewCell { 422 | [self reloadCellFixedHeight:NSNotFound 423 | tableViewCell:tableViewCell]; 424 | } 425 | 426 | - (void)reloadCellFixedHeight:(NSInteger)height 427 | tableViewCell:(ZHTableViewCell *)tableViewCell { 428 | [self reloadCellHeight:height 429 | tableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *cell) { 430 | return [cell isEqual:tableViewCell]; 431 | }]; 432 | } 433 | 434 | - (void)reloadCellAutomicHeightWithGroupIndex:(NSUInteger)groupIndex 435 | cellIndex:(NSUInteger)cellIndex { 436 | [self reloadCellFixedHeight:NSNotFound 437 | groupIndex:groupIndex 438 | cellIndex:cellIndex]; 439 | } 440 | 441 | - (void)reloadCellFixedHeight:(CGFloat)height 442 | groupIndex:(NSUInteger)groupIndex 443 | cellIndex:(NSUInteger)cellIndex { 444 | [self reloadCellHeight:height 445 | tableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell) { 446 | return section == groupIndex && row == cellIndex; 447 | }]; 448 | } 449 | 450 | - (void)reloadCellHeight:(CGFloat)height 451 | tableViewCellConfig:(BOOL (^)(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell))tableViewCellConfig { 452 | if (!tableViewCellConfig) { 453 | return; 454 | } 455 | [[self filterCellWithConfig:tableViewCellConfig] enumerateObjectsUsingBlock:^(ZHTableViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 456 | obj.height = height; 457 | [self.tableView beginUpdates]; 458 | [self.tableView endUpdates]; 459 | }];; 460 | } 461 | 462 | @end 463 | 464 | @implementation ZHTableViewDataSource (ReloadCell) 465 | 466 | - (void)reloadCellWithIdentifier:(NSString *)identienfier { 467 | [self reloadCellWithTableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell) { 468 | return [tableViewCell.identifier isEqualToString:identienfier]; 469 | }]; 470 | } 471 | 472 | - (void)reloadCellWithClassName:(Class)className { 473 | [self reloadCellWithTableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell) { 474 | return tableViewCell.anyClass == className; 475 | }]; 476 | } 477 | 478 | - (void)reloadCellWithTableViewCell:(ZHTableViewCell *)tableViewCell { 479 | [self reloadCellWithTableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell1) { 480 | return [tableViewCell isEqual:tableViewCell1]; 481 | }]; 482 | } 483 | 484 | - (void)reloadCellWithGroupIndex:(NSUInteger)groupIndex 485 | cellIndex:(NSUInteger)cellIndex { 486 | [self reloadCellWithTableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell1) { 487 | return groupIndex == section && cellIndex == row; 488 | }]; 489 | } 490 | 491 | - (void)reloadCellWithTableViewCellConfig:(BOOL (^)(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell))tableViewCellConfig { 492 | if (!tableViewCellConfig) { 493 | return; 494 | } 495 | [[self filterCellWithConfig:tableViewCellConfig] enumerateObjectsUsingBlock:^(ZHTableViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 496 | NSMutableArray *indexPaths = [NSMutableArray array]; 497 | for (NSUInteger i = 0; i < obj.cellNumber; i++) { 498 | NSIndexPath *indexPath = [self indexPathWithTableViewCell:obj]; 499 | [indexPaths addObject:[NSIndexPath indexPathForRow:(indexPath.row + i) inSection:indexPath.section]]; 500 | } 501 | [self updatesTableView:^{ 502 | [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; 503 | }]; 504 | }]; 505 | } 506 | 507 | - (NSMutableArray *)indexPathsWithTableViewCell:(ZHTableViewCell *)tableViewCell { 508 | NSMutableArray *indexPaths = [NSMutableArray array]; 509 | for (NSUInteger i = 0; i < tableViewCell.cellNumber; i++) { 510 | NSIndexPath *indexPath = [self indexPathWithTableViewCell:tableViewCell]; 511 | [indexPaths addObject:[NSIndexPath indexPathForRow:(indexPath.row + i) inSection:indexPath.section]]; 512 | } 513 | return indexPaths; 514 | } 515 | 516 | @end 517 | 518 | @implementation ZHTableViewDataSource (ReloadData) 519 | 520 | - (void)reloadCellWithDataCount:(NSUInteger)dataCount 521 | identifier:(NSString *)identifier { 522 | [self reloadCellWithDataCount:dataCount tableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell) { 523 | return [tableViewCell.identifier isEqualToString:identifier]; 524 | }]; 525 | } 526 | 527 | - (void)reloadCellWithDataCount:(NSUInteger)dataCount 528 | className:(Class)className { 529 | [self reloadCellWithDataCount:dataCount tableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell) { 530 | return tableViewCell.anyClass == className; 531 | }]; 532 | } 533 | 534 | - (void)reloadCellWithDataCount:(NSUInteger)dataCount 535 | tableViewCell:(ZHTableViewCell *)tableViewCell { 536 | [self reloadCellWithDataCount:dataCount tableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell1) { 537 | return [tableViewCell isEqual:tableViewCell1]; 538 | }]; 539 | } 540 | 541 | - (void)reloadCellWithDataCount:(NSUInteger)dataCount 542 | groupIndex:(NSUInteger)groupIndex 543 | cellIndex:(NSUInteger)cellIndex { 544 | [self reloadCellWithDataCount:dataCount tableViewCellConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell1) { 545 | return groupIndex == section && cellIndex == row; 546 | }]; 547 | } 548 | 549 | - (void)reloadCellWithDataCount:(NSUInteger)dataCount 550 | tableViewCellConfig:(BOOL (^)(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell))tableViewCellConfig { 551 | [[self filterCellWithConfig:tableViewCellConfig] enumerateObjectsUsingBlock:^(ZHTableViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 552 | NSUInteger cellNumber = obj.cellNumber; 553 | NSIndexPath *indexPath = [self indexPathWithTableViewCell:obj]; 554 | obj.cellNumber = dataCount; 555 | if (cellNumber == dataCount) { 556 | NSMutableArray *indexPaths = [NSMutableArray array]; 557 | for (NSUInteger i = 0; i < cellNumber; i++) { 558 | [indexPaths addObject:[NSIndexPath indexPathForRow:(indexPath.row + i) inSection:indexPath.section]]; 559 | } 560 | [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; 561 | } else if (cellNumber < dataCount) { 562 | NSMutableArray *indexPaths = [NSMutableArray array]; 563 | NSMutableArray *insertIndexPaths = [NSMutableArray array]; 564 | for (NSUInteger i = 0; i < dataCount; i++) { 565 | if (i < cellNumber) { 566 | [indexPaths addObject:[NSIndexPath indexPathForRow:(indexPath.row + i) inSection:indexPath.section]]; 567 | } else { 568 | [insertIndexPaths addObject:[NSIndexPath indexPathForRow:(indexPath.row + i) inSection:indexPath.section]]; 569 | } 570 | } 571 | [self updatesTableView:^{ 572 | [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; 573 | [self.tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; 574 | }]; 575 | } else { 576 | NSMutableArray *indexPaths = [NSMutableArray array]; 577 | NSMutableArray *deleteIndexPath = [NSMutableArray array]; 578 | for (NSUInteger i = 0; i < cellNumber; i++) { 579 | if (i < dataCount) { 580 | [indexPaths addObject:[NSIndexPath indexPathForRow:(indexPath.row + i) inSection:indexPath.section]]; 581 | } else { 582 | [deleteIndexPath addObject:[NSIndexPath indexPathForRow:(indexPath.row + i) inSection:indexPath.section]]; 583 | } 584 | } 585 | [self updatesTableView:^{ 586 | [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; 587 | [self.tableView deleteRowsAtIndexPaths:deleteIndexPath withRowAnimation:UITableViewRowAnimationAutomatic]; 588 | }]; 589 | } 590 | }]; 591 | } 592 | 593 | - (void)updatesTableView:(void(^)(void))update { 594 | if (@available(iOS 11.0, *)) { 595 | [self.tableView performBatchUpdates:update completion:nil]; 596 | } else { 597 | [self.tableView beginUpdates]; 598 | update(); 599 | [self.tableView endUpdates]; 600 | } 601 | } 602 | 603 | @end 604 | 605 | @implementation ZHTableViewDataSource (Cell) 606 | 607 | - (NSArray *)filterCellWithConfig:(BOOL (^)(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell))config { 608 | NSMutableArray *filterResults = [NSMutableArray array]; 609 | __block NSUInteger section = 0; 610 | [self.groups enumerateObjectsUsingBlock:^(ZHTableViewGroup * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 611 | section = idx; 612 | __block NSUInteger row = 0; 613 | [obj.cells enumerateObjectsUsingBlock:^(ZHTableViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 614 | row = idx; 615 | if (config(section,row,obj)) { 616 | [filterResults addObject:obj]; 617 | } 618 | }]; 619 | }]; 620 | return filterResults; 621 | } 622 | 623 | - (NSIndexPath *)indexPathWithTableViewCell:(ZHTableViewCell *)tableViewCell { 624 | __block NSIndexPath *indexPath; 625 | __block NSUInteger section = 0; 626 | [self.groups enumerateObjectsUsingBlock:^(ZHTableViewGroup * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 627 | section = idx; 628 | __block NSUInteger row = 0; 629 | [obj.cells enumerateObjectsUsingBlock:^(ZHTableViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 630 | if ([tableViewCell isEqual:obj]) { 631 | indexPath = [NSIndexPath indexPathForRow:row inSection:section]; 632 | *stop = YES; 633 | return; 634 | } 635 | row += obj.cellNumber; 636 | }]; 637 | }]; 638 | return indexPath; 639 | } 640 | 641 | @end 642 | 643 | @implementation ZHTableViewDataSource (Hidden) 644 | 645 | - (void)reloadAllHiddenCell { 646 | NSMutableArray *needReloadIndexPath = [NSMutableArray array]; 647 | [[self filterCellWithConfig:^BOOL(NSUInteger section, NSUInteger row, ZHTableViewCell *tableViewCell) { 648 | return YES; 649 | }] enumerateObjectsUsingBlock:^(ZHTableViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 650 | if (!obj.hiddenBlock) { 651 | return; 652 | } 653 | [[self indexPathsWithTableViewCell:obj] enumerateObjectsUsingBlock:^(NSIndexPath * _Nonnull indexPath, NSUInteger idx, BOOL * _Nonnull stop) { 654 | NSIndexPath *realIndexPath = [NSIndexPath indexPathForRow:idx inSection:0]; 655 | UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; 656 | if (cell && cell.isHidden == [obj isHiddenWithIndexPath:realIndexPath]) { 657 | return; 658 | } 659 | [needReloadIndexPath addObject:indexPath]; 660 | }]; 661 | }] ; 662 | [self updatesTableView:^{ 663 | [self.tableView reloadRowsAtIndexPaths:needReloadIndexPath 664 | withRowAnimation:UITableViewRowAnimationAutomatic]; 665 | }]; 666 | } 667 | 668 | @end 669 | NS_ASSUME_NONNULL_END 670 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewGroup.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/3/18. 6 | // 7 | // 8 | 9 | #import 10 | #import "ZHTableViewHeaderFooter.h" 11 | #import "ZHTableViewCell.h" 12 | 13 | typedef void(^ZHTableViewGroupAddCellCompletionHandle)(ZHTableViewCell *cell); 14 | typedef void(^ZHTableViewGroupAddHeaderFooterCompletionHandle)(ZHTableViewHeaderFooter *headerFooter); 15 | 16 | 17 | 18 | @interface ZHTableViewGroup : NSObject 19 | 20 | @property (nonatomic, strong) ZHTableViewHeaderFooter *header; 21 | @property (nonatomic, strong) ZHTableViewHeaderFooter *footer; 22 | @property (nonatomic, assign, readonly) NSInteger cellCount; 23 | @property (nonatomic, strong, readonly) NSMutableArray *cells; 24 | 25 | - (void)registerHeaderFooterCellWithTableView:(UITableView *)tableView; 26 | 27 | - (UITableViewCell *)cellForTableViewWithTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath config:(BOOL)config; 28 | 29 | - (ZHTableViewCell *)addCellWithCompletionHandle:(ZHTableViewGroupAddCellCompletionHandle)completionHandle; 30 | 31 | - (void)addHeaderWithCompletionHandle:(ZHTableViewGroupAddHeaderFooterCompletionHandle)completionHandle; 32 | 33 | - (void)addFooterWithCompletionHandle:(ZHTableViewGroupAddHeaderFooterCompletionHandle)completionHandle; 34 | 35 | - (ZHTableViewCell *)tableViewCellForIndexPath:(NSIndexPath *)indexPath; 36 | 37 | - (UITableViewHeaderFooterView *)headerFooterForStyle:(ZHTableViewHeaderFooterStyle)style tableView:(UITableView *)tableView section:(NSUInteger)section; 38 | 39 | - (NSIndexPath *)indexPathWithCell:(ZHTableViewCell *)cell indexPath:(NSIndexPath *)indexPath; 40 | 41 | - (void)tableViewCell:(ZHTableViewCell *)tableViewCell 42 | configCell:(UITableViewCell *)cell 43 | atIndexPath:(NSIndexPath *)indexPath; 44 | 45 | - (ZHTableViewGroup *(^)(ZHTableViewHeaderFooter *))tableHeader; 46 | - (ZHTableViewGroup *(^)(ZHTableViewHeaderFooter *))tableFooter; 47 | 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewGroup.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewGroup.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/3/18. 6 | // 7 | // 8 | 9 | #import "ZHTableViewGroup.h" 10 | 11 | @interface ZHTableViewGroup () 12 | 13 | @property (nonatomic, strong) NSMutableArray *cells; 14 | 15 | @end 16 | 17 | @implementation ZHTableViewGroup 18 | 19 | - (void)registerHeaderFooterCellWithTableView:(UITableView *)tableView { 20 | if (self.header && self.header.identifier) { 21 | [tableView registerClass:self.header.anyClass forHeaderFooterViewReuseIdentifier:self.header.identifier]; 22 | } 23 | if (self.footer && self.footer.identifier) { 24 | [tableView registerClass:self.footer.anyClass forHeaderFooterViewReuseIdentifier:self.footer.identifier]; 25 | } 26 | for (ZHTableViewCell *tableViewCell in self.cells) { 27 | if (tableViewCell.identifier) { 28 | [tableView registerClass:tableViewCell.anyClass forCellReuseIdentifier:tableViewCell.identifier]; 29 | } 30 | } 31 | } 32 | 33 | - (ZHTableViewCell *)addCellWithCompletionHandle:(ZHTableViewGroupAddCellCompletionHandle)completionHandle { 34 | ZHTableViewCell *cell = [[ZHTableViewCell alloc] init]; 35 | if (completionHandle) { 36 | completionHandle(cell); 37 | } 38 | [self.cells addObject:cell]; 39 | return cell; 40 | } 41 | 42 | - (void)addHeaderWithCompletionHandle:(ZHTableViewGroupAddHeaderFooterCompletionHandle)completionHandle { 43 | ZHTableViewHeaderFooter *header= [[ZHTableViewHeaderFooter alloc] initWithStyle:ZHTableViewHeaderFooterStyleHeader]; 44 | if (completionHandle) { 45 | completionHandle(header); 46 | } 47 | _header = header; 48 | } 49 | 50 | - (void)addFooterWithCompletionHandle:(ZHTableViewGroupAddHeaderFooterCompletionHandle)completionHandle { 51 | ZHTableViewHeaderFooter *footer = [[ZHTableViewHeaderFooter alloc] initWithStyle:ZHTableViewHeaderFooterStyleFooter]; 52 | if (completionHandle) { 53 | completionHandle(footer); 54 | } 55 | _footer = footer; 56 | } 57 | 58 | - (UITableViewCell *)cellForTableViewWithTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath config:(BOOL)config{ 59 | if (!tableView) { 60 | return nil; 61 | } 62 | ZHTableViewCell *tableViewCell = [self tableViewCellForIndexPath:indexPath]; 63 | if (!tableViewCell) { 64 | return nil; 65 | } 66 | if (!tableViewCell.identifier) { 67 | return nil; 68 | } 69 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableViewCell.identifier]; 70 | if (config) { 71 | [self tableViewCell:tableViewCell 72 | configCell:cell 73 | atIndexPath:indexPath]; 74 | } 75 | return cell; 76 | } 77 | 78 | - (void)tableViewCell:(ZHTableViewCell *)tableViewCell 79 | configCell:(UITableViewCell *)cell 80 | atIndexPath:(NSIndexPath *)indexPath { 81 | NSIndexPath *really = [self indexPathWithCell:tableViewCell 82 | indexPath:indexPath]; 83 | [tableViewCell configCellWithCell:cell 84 | indexPath:really]; 85 | } 86 | 87 | - (NSIndexPath *)indexPathWithCell:(ZHTableViewCell *)cell indexPath:(NSIndexPath *)indexPath { 88 | __block NSUInteger startIndex = 0; 89 | [self.cells enumerateObjectsUsingBlock:^(ZHTableViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 90 | if (obj == cell) { 91 | *stop = YES; 92 | return; 93 | } 94 | startIndex += obj.cellNumber; 95 | }]; 96 | return [NSIndexPath indexPathForRow:indexPath.row - startIndex inSection:indexPath.section]; 97 | } 98 | 99 | - (ZHTableViewCell *)tableViewCellForIndexPath:(NSIndexPath *)indexPath { 100 | if (indexPath.row >= self.cellCount) { 101 | return nil; 102 | } 103 | NSInteger count = 0; 104 | ZHTableViewCell *tableViewCell; 105 | for (NSUInteger i = 0; i < self.cells.count; i ++) { 106 | ZHTableViewCell *cell = self.cells[i]; 107 | NSUInteger tempCount = count; 108 | count += cell.cellNumber; 109 | if (indexPath.row >= tempCount && indexPath.row < count) { 110 | tableViewCell = cell; 111 | break; 112 | } 113 | } 114 | return tableViewCell; 115 | } 116 | 117 | - (UITableViewHeaderFooterView *)headerFooterForStyle:(ZHTableViewHeaderFooterStyle)style tableView:(UITableView *)tableView section:(NSUInteger)section { 118 | if (!tableView) { 119 | return nil; 120 | } 121 | ZHTableViewHeaderFooter *headerFooter; 122 | switch (style) { 123 | case ZHTableViewHeaderFooterStyleHeader: { 124 | headerFooter = self.header; 125 | } 126 | break; 127 | case ZHTableViewHeaderFooterStyleFooter: { 128 | headerFooter = self.footer; 129 | } 130 | break; 131 | } 132 | if (!headerFooter) { 133 | return nil; 134 | } 135 | if (!headerFooter.identifier) { 136 | return nil; 137 | } 138 | UITableViewHeaderFooterView *headerFooterView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerFooter.identifier]; 139 | [headerFooter setHeaderFooter:headerFooterView section:section]; 140 | return headerFooterView; 141 | } 142 | 143 | 144 | - (NSMutableArray *)cells { 145 | if (!_cells) { 146 | _cells = [NSMutableArray array]; 147 | } 148 | return _cells; 149 | } 150 | 151 | - (NSInteger)cellCount { 152 | NSInteger count = 0; 153 | for (ZHTableViewCell *tableViewCell in self.cells) { 154 | count += tableViewCell.cellNumber; 155 | } 156 | return count; 157 | } 158 | 159 | - (ZHTableViewGroup *(^)(ZHTableViewHeaderFooter *))tableHeader { 160 | return ^(ZHTableViewHeaderFooter *header) { 161 | return self; 162 | }; 163 | } 164 | 165 | - (ZHTableViewGroup *(^)(ZHTableViewHeaderFooter *))tableFooter { 166 | return ^(ZHTableViewHeaderFooter *footer) { 167 | return self; 168 | }; 169 | } 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewGroupObjc.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewGroupObjc.h 3 | // ZHTableViewGroupObjc 4 | // 5 | // Created by josercc on 2020/3/3. 6 | // Copyright © 2020 josercc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for ZHTableViewGroupObjc. 12 | FOUNDATION_EXPORT double ZHTableViewGroupObjcVersionNumber; 13 | 14 | //! Project version string for ZHTableViewGroupObjc. 15 | FOUNDATION_EXPORT const unsigned char ZHTableViewGroupObjcVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | #import "ZHTableViewDataSource.h" 20 | #import "ZHCollectionViewDataSource.h" 21 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewHeaderFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewHeaderFooter.h 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/3/18. 6 | // 7 | // 8 | 9 | #import "ZHTableViewBaseModel.h" 10 | 11 | /** 12 | * 配置UITableViewHeaderFooterView的回调 13 | 14 | @param headerFooterView 需要设置配置的UITableViewHeaderFooterView 15 | @param section 需要配置的组 16 | */ 17 | typedef void(^ZHTableViewHeaderFooterCompletionHandle)(UITableViewHeaderFooterView *headerFooterView, NSUInteger section); 18 | 19 | typedef NS_ENUM(NSUInteger, ZHTableViewHeaderFooterStyle) { 20 | ZHTableViewHeaderFooterStyleHeader, 21 | ZHTableViewHeaderFooterStyleFooter 22 | }; 23 | 24 | @interface ZHTableViewHeaderFooter : ZHTableViewBaseModel 25 | 26 | @property (nonatomic, assign) ZHTableViewHeaderFooterStyle style; 27 | 28 | @property (nonatomic, copy) CGFloat(^customHeightBlock)(HeaderFooter view, NSUInteger section); 29 | 30 | /** 31 | * 根据样式进行初始化ZHTableViewHeaderFooter 32 | 33 | @param style 样式 34 | @return ZHTableViewHeaderFooter 35 | */ 36 | - (instancetype)initWithStyle:(ZHTableViewHeaderFooterStyle)style; 37 | 38 | /** 39 | * 执行配置UITableViewHeaderFooterView 40 | 41 | @param headerFooter UITableViewHeaderFooterView的泛型 42 | @param section 配置所在的Section 43 | */ 44 | - (void)setHeaderFooter:(HeaderFooter)headerFooter section:(NSUInteger)section; 45 | 46 | /** 47 | * 配置Header的回调 48 | 49 | @param block 配置的Block 50 | */ 51 | - (void)configurationHeader:(void(^)(HeaderFooter header, NSUInteger section))block; 52 | /** 53 | * 配置Footer的回调 54 | 55 | @param block 配置的Block 56 | */ 57 | - (void)configurationFooter:(void(^)(HeaderFooter footer, NSUInteger section))block; 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/ZHTableViewHeaderFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZHTableViewHeaderFooter.m 3 | // Pods 4 | // 5 | // Created by 张行 on 2017/3/18. 6 | // 7 | // 8 | 9 | #import "ZHTableViewHeaderFooter.h" 10 | 11 | @implementation ZHTableViewHeaderFooter { 12 | ZHTableViewHeaderFooterCompletionHandle _headerBlock; 13 | ZHTableViewHeaderFooterCompletionHandle _footerBlock; 14 | } 15 | 16 | - (instancetype)initWithStyle:(ZHTableViewHeaderFooterStyle)style { 17 | if (self = [super init]) { 18 | _style = style; 19 | } 20 | return self; 21 | } 22 | 23 | - (void)setHeaderFooter:(UITableViewHeaderFooterView *)headerFooter section:(NSUInteger)section { 24 | switch (self.style) { 25 | case ZHTableViewHeaderFooterStyleHeader: { 26 | if (_headerBlock) { 27 | _headerBlock(headerFooter,section); 28 | } 29 | } 30 | break; 31 | case ZHTableViewHeaderFooterStyleFooter: { 32 | if (_footerBlock) { 33 | _footerBlock(headerFooter,section); 34 | } 35 | } 36 | break; 37 | default: 38 | break; 39 | } 40 | } 41 | 42 | - (void)configurationHeader:(void (^)(UITableViewHeaderFooterView *header, NSUInteger section))block { 43 | _headerBlock = block; 44 | } 45 | 46 | -(void)configurationFooter:(void (^)(UITableViewHeaderFooterView *footer, NSUInteger section))block { 47 | _footerBlock = block; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHAutoConfigurationCollectionViewDelegate.h: -------------------------------------------------------------------------------- 1 | ../ZHAutoConfigurationCollectionViewDelegate.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHAutoConfigurationTableViewDelegate.h: -------------------------------------------------------------------------------- 1 | ../ZHAutoConfigurationTableViewDelegate.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHCollectionViewBaseModel.h: -------------------------------------------------------------------------------- 1 | ../ZHCollectionViewBaseModel.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHCollectionViewCell.h: -------------------------------------------------------------------------------- 1 | ../ZHCollectionViewCell.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHCollectionViewDataSource.h: -------------------------------------------------------------------------------- 1 | ../ZHCollectionViewDataSource.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHCollectionViewGroup.h: -------------------------------------------------------------------------------- 1 | ../ZHCollectionViewGroup.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHCollectionViewHeaderFooter.h: -------------------------------------------------------------------------------- 1 | ../ZHCollectionViewHeaderFooter.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHTableViewBaseModel.h: -------------------------------------------------------------------------------- 1 | ../ZHTableViewBaseModel.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHTableViewCell.h: -------------------------------------------------------------------------------- 1 | ../ZHTableViewCell.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHTableViewDataSource.h: -------------------------------------------------------------------------------- 1 | ../ZHTableViewDataSource.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHTableViewGroup.h: -------------------------------------------------------------------------------- 1 | ../ZHTableViewGroup.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHTableViewGroupObjc.h: -------------------------------------------------------------------------------- 1 | ../ZHTableViewGroupObjc.h -------------------------------------------------------------------------------- /ZHTableViewGroupExample/ZHTableViewGroupObjc/include/ZHTableViewHeaderFooter.h: -------------------------------------------------------------------------------- 1 | ../ZHTableViewHeaderFooter.h -------------------------------------------------------------------------------- /ZHTableViewGroupObjc.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ZHTableViewGroup.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ZHTableViewGroupObjc' 11 | s.version = '3.5.5' 12 | s.summary = 'Manger UITableView DataSource More Cell Style' 13 | 14 | s.homepage = 'https://github.com/josercc/ZHTableViewGroup' 15 | s.license = { :type => 'MIT', :file => 'LICENSE' } 16 | s.author = { '15038777234' => '15038777234@163.com' } 17 | s.source = { :git => 'https://github.com/josercc/ZHTableViewGroup.git', :tag => s.version.to_s } 18 | s.ios.deployment_target = '8.0' 19 | s.source_files = 'ZHTableViewGroupExample/ZHTableViewGroupObjc/**/*.{h,m}' 20 | end 21 | -------------------------------------------------------------------------------- /images/2019-08-20-034515.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josercc/ZHTableViewGroup/30d5a4246d49d70bfeb3465ad6fe931bbbe7acf2/images/2019-08-20-034515.png -------------------------------------------------------------------------------- /images/2019-08-20-035055.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josercc/ZHTableViewGroup/30d5a4246d49d70bfeb3465ad6fe931bbbe7acf2/images/2019-08-20-035055.png -------------------------------------------------------------------------------- /images/image-20190820115521632.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josercc/ZHTableViewGroup/30d5a4246d49d70bfeb3465ad6fe931bbbe7acf2/images/image-20190820115521632.png -------------------------------------------------------------------------------- /images/image-20190820115538881.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josercc/ZHTableViewGroup/30d5a4246d49d70bfeb3465ad6fe931bbbe7acf2/images/image-20190820115538881.png -------------------------------------------------------------------------------- /images/image-20190820115647037.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josercc/ZHTableViewGroup/30d5a4246d49d70bfeb3465ad6fe931bbbe7acf2/images/image-20190820115647037.png -------------------------------------------------------------------------------- /images/image-20190820115743952.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josercc/ZHTableViewGroup/30d5a4246d49d70bfeb3465ad6fe931bbbe7acf2/images/image-20190820115743952.png --------------------------------------------------------------------------------