├── ForwardProxy ├── .DS_Store ├── ForwardProxy.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── linitial.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── linitial.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist └── ForwardProxy │ ├── .DS_Store │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Example │ ├── .DS_Store │ ├── ExampleDataManager.h │ ├── ExampleDataManager.m │ ├── ExampleModel.h │ ├── ExampleModel.m │ ├── ExampleTableViewCell.h │ ├── ExampleTableViewCell.m │ ├── ViewController.h │ └── ViewController.m │ ├── ForwadProxy │ ├── .DS_Store │ ├── Category │ │ ├── NSObject+MutiplyProxy.h │ │ ├── NSObject+MutiplyProxy.m │ │ ├── NSObject+Next.h │ │ ├── NSObject+Next.m │ │ ├── UIScrollView+Addition.h │ │ └── UIScrollView+Addition.m │ ├── Config │ │ ├── RCCellConfig.h │ │ ├── RCCellConfig.m │ │ ├── RCHeaderFooterConfig.h │ │ ├── RCHeaderFooterConfig.m │ │ ├── RCSection.h │ │ └── RCSection.m │ ├── Implement │ │ ├── RCCollectionViewImplement.h │ │ ├── RCCollectionViewImplement.m │ │ ├── RCTableViewImplement.h │ │ └── RCTableViewImplement.m │ ├── Protocol │ │ ├── RCCellConfigProtocol.h │ │ ├── RCCellProtocol.h │ │ ├── RCHeaderFooterConfigProtocol.h │ │ └── RCHeaderFooterProtocol.h │ └── Proxy │ │ ├── RCProxy.h │ │ └── RCProxy.m │ ├── Info.plist │ ├── SceneDelegate.h │ ├── SceneDelegate.m │ └── main.m └── README.md /ForwardProxy/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecheLi/ForwardProxy/1d7941f9234a6114c624d54a73ebc1b858fb0eb9/ForwardProxy/.DS_Store -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4373F03923FE69C4003A51A2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F03823FE69C4003A51A2 /* AppDelegate.m */; }; 11 | 4373F03C23FE69C4003A51A2 /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F03B23FE69C4003A51A2 /* SceneDelegate.m */; }; 12 | 4373F04223FE69C4003A51A2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4373F04023FE69C4003A51A2 /* Main.storyboard */; }; 13 | 4373F04423FE69C6003A51A2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4373F04323FE69C6003A51A2 /* Assets.xcassets */; }; 14 | 4373F04723FE69C6003A51A2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4373F04523FE69C6003A51A2 /* LaunchScreen.storyboard */; }; 15 | 4373F04A23FE69C6003A51A2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F04923FE69C6003A51A2 /* main.m */; }; 16 | 4373F05923FE6A8B003A51A2 /* RCProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F05823FE6A8B003A51A2 /* RCProxy.m */; }; 17 | 4373F05C23FE6ADB003A51A2 /* NSObject+Next.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F05B23FE6ADB003A51A2 /* NSObject+Next.m */; }; 18 | 4373F05F23FE718D003A51A2 /* UIScrollView+Addition.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F05E23FE718D003A51A2 /* UIScrollView+Addition.m */; }; 19 | 4373F06623FE72E5003A51A2 /* RCCellConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F06523FE72E5003A51A2 /* RCCellConfig.m */; }; 20 | 4373F06923FE72FD003A51A2 /* RCSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F06823FE72FD003A51A2 /* RCSection.m */; }; 21 | 4373F06C23FE7313003A51A2 /* RCHeaderFooterConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F06B23FE7313003A51A2 /* RCHeaderFooterConfig.m */; }; 22 | 4373F07023FE7777003A51A2 /* RCTableViewImplement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F06F23FE7777003A51A2 /* RCTableViewImplement.m */; }; 23 | 4373F07323FE7783003A51A2 /* RCCollectionViewImplement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F07223FE7783003A51A2 /* RCCollectionViewImplement.m */; }; 24 | 4373F07723FE84FE003A51A2 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F07523FE84FE003A51A2 /* ViewController.m */; }; 25 | 4373F08223FE8565003A51A2 /* ExampleModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F08123FE8565003A51A2 /* ExampleModel.m */; }; 26 | 4373F08623FE8579003A51A2 /* ExampleTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F08423FE8579003A51A2 /* ExampleTableViewCell.m */; }; 27 | 4373F08A23FE8C99003A51A2 /* ExampleDataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4373F08923FE8C99003A51A2 /* ExampleDataManager.m */; }; 28 | CEFE2EF124EB704800CC9AB3 /* NSObject+MutiplyProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFE2EF024EB704800CC9AB3 /* NSObject+MutiplyProxy.m */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 4373F03423FE69C4003A51A2 /* ForwardProxy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ForwardProxy.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | 4373F03723FE69C4003A51A2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 34 | 4373F03823FE69C4003A51A2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 35 | 4373F03A23FE69C4003A51A2 /* SceneDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SceneDelegate.h; sourceTree = ""; }; 36 | 4373F03B23FE69C4003A51A2 /* SceneDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SceneDelegate.m; sourceTree = ""; }; 37 | 4373F04123FE69C4003A51A2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 38 | 4373F04323FE69C6003A51A2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 39 | 4373F04623FE69C6003A51A2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 40 | 4373F04823FE69C6003A51A2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | 4373F04923FE69C6003A51A2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 42 | 4373F05723FE6A8B003A51A2 /* RCProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCProxy.h; sourceTree = ""; }; 43 | 4373F05823FE6A8B003A51A2 /* RCProxy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCProxy.m; sourceTree = ""; }; 44 | 4373F05A23FE6ADB003A51A2 /* NSObject+Next.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSObject+Next.h"; sourceTree = ""; }; 45 | 4373F05B23FE6ADB003A51A2 /* NSObject+Next.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Next.m"; sourceTree = ""; }; 46 | 4373F05D23FE718D003A51A2 /* UIScrollView+Addition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+Addition.h"; sourceTree = ""; }; 47 | 4373F05E23FE718D003A51A2 /* UIScrollView+Addition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+Addition.m"; sourceTree = ""; }; 48 | 4373F06023FE71F5003A51A2 /* RCCellProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCCellProtocol.h; sourceTree = ""; }; 49 | 4373F06123FE7202003A51A2 /* RCHeaderFooterProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCHeaderFooterProtocol.h; sourceTree = ""; }; 50 | 4373F06223FE722B003A51A2 /* RCCellConfigProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCCellConfigProtocol.h; sourceTree = ""; }; 51 | 4373F06323FE723B003A51A2 /* RCHeaderFooterConfigProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCHeaderFooterConfigProtocol.h; sourceTree = ""; }; 52 | 4373F06423FE72E5003A51A2 /* RCCellConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCCellConfig.h; sourceTree = ""; }; 53 | 4373F06523FE72E5003A51A2 /* RCCellConfig.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCCellConfig.m; sourceTree = ""; }; 54 | 4373F06723FE72FD003A51A2 /* RCSection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCSection.h; sourceTree = ""; }; 55 | 4373F06823FE72FD003A51A2 /* RCSection.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCSection.m; sourceTree = ""; }; 56 | 4373F06A23FE7313003A51A2 /* RCHeaderFooterConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCHeaderFooterConfig.h; sourceTree = ""; }; 57 | 4373F06B23FE7313003A51A2 /* RCHeaderFooterConfig.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCHeaderFooterConfig.m; sourceTree = ""; }; 58 | 4373F06E23FE7777003A51A2 /* RCTableViewImplement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTableViewImplement.h; sourceTree = ""; }; 59 | 4373F06F23FE7777003A51A2 /* RCTableViewImplement.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTableViewImplement.m; sourceTree = ""; }; 60 | 4373F07123FE7783003A51A2 /* RCCollectionViewImplement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCCollectionViewImplement.h; sourceTree = ""; }; 61 | 4373F07223FE7783003A51A2 /* RCCollectionViewImplement.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCCollectionViewImplement.m; sourceTree = ""; }; 62 | 4373F07523FE84FE003A51A2 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 63 | 4373F07623FE84FE003A51A2 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 64 | 4373F08023FE8565003A51A2 /* ExampleModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExampleModel.h; sourceTree = ""; }; 65 | 4373F08123FE8565003A51A2 /* ExampleModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleModel.m; sourceTree = ""; }; 66 | 4373F08323FE8579003A51A2 /* ExampleTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExampleTableViewCell.h; sourceTree = ""; }; 67 | 4373F08423FE8579003A51A2 /* ExampleTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleTableViewCell.m; sourceTree = ""; }; 68 | 4373F08823FE8C99003A51A2 /* ExampleDataManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExampleDataManager.h; sourceTree = ""; }; 69 | 4373F08923FE8C99003A51A2 /* ExampleDataManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleDataManager.m; sourceTree = ""; }; 70 | CEFE2EEF24EB704800CC9AB3 /* NSObject+MutiplyProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MutiplyProxy.h"; sourceTree = ""; }; 71 | CEFE2EF024EB704800CC9AB3 /* NSObject+MutiplyProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MutiplyProxy.m"; sourceTree = ""; }; 72 | /* End PBXFileReference section */ 73 | 74 | /* Begin PBXFrameworksBuildPhase section */ 75 | 4373F03123FE69C4003A51A2 /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | /* End PBXFrameworksBuildPhase section */ 83 | 84 | /* Begin PBXGroup section */ 85 | 4373F02B23FE69C4003A51A2 = { 86 | isa = PBXGroup; 87 | children = ( 88 | 4373F03623FE69C4003A51A2 /* ForwardProxy */, 89 | 4373F03523FE69C4003A51A2 /* Products */, 90 | ); 91 | sourceTree = ""; 92 | }; 93 | 4373F03523FE69C4003A51A2 /* Products */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 4373F03423FE69C4003A51A2 /* ForwardProxy.app */, 97 | ); 98 | name = Products; 99 | sourceTree = ""; 100 | }; 101 | 4373F03623FE69C4003A51A2 /* ForwardProxy */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 4373F05123FE6A6D003A51A2 /* ForwadProxy */, 105 | 4373F03723FE69C4003A51A2 /* AppDelegate.h */, 106 | 4373F03823FE69C4003A51A2 /* AppDelegate.m */, 107 | 4373F03A23FE69C4003A51A2 /* SceneDelegate.h */, 108 | 4373F03B23FE69C4003A51A2 /* SceneDelegate.m */, 109 | 4373F07423FE84FE003A51A2 /* Example */, 110 | 4373F04023FE69C4003A51A2 /* Main.storyboard */, 111 | 4373F04323FE69C6003A51A2 /* Assets.xcassets */, 112 | 4373F04523FE69C6003A51A2 /* LaunchScreen.storyboard */, 113 | 4373F04823FE69C6003A51A2 /* Info.plist */, 114 | 4373F04923FE69C6003A51A2 /* main.m */, 115 | ); 116 | path = ForwardProxy; 117 | sourceTree = ""; 118 | }; 119 | 4373F05123FE6A6D003A51A2 /* ForwadProxy */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 4373F06D23FE775C003A51A2 /* Implement */, 123 | 4373F05223FE6A6D003A51A2 /* Proxy */, 124 | 4373F05323FE6A6D003A51A2 /* Category */, 125 | 4373F05423FE6A6D003A51A2 /* Config */, 126 | 4373F05623FE6A6D003A51A2 /* Protocol */, 127 | ); 128 | path = ForwadProxy; 129 | sourceTree = ""; 130 | }; 131 | 4373F05223FE6A6D003A51A2 /* Proxy */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 4373F05723FE6A8B003A51A2 /* RCProxy.h */, 135 | 4373F05823FE6A8B003A51A2 /* RCProxy.m */, 136 | ); 137 | path = Proxy; 138 | sourceTree = ""; 139 | }; 140 | 4373F05323FE6A6D003A51A2 /* Category */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 4373F05A23FE6ADB003A51A2 /* NSObject+Next.h */, 144 | 4373F05B23FE6ADB003A51A2 /* NSObject+Next.m */, 145 | CEFE2EEF24EB704800CC9AB3 /* NSObject+MutiplyProxy.h */, 146 | CEFE2EF024EB704800CC9AB3 /* NSObject+MutiplyProxy.m */, 147 | 4373F05D23FE718D003A51A2 /* UIScrollView+Addition.h */, 148 | 4373F05E23FE718D003A51A2 /* UIScrollView+Addition.m */, 149 | ); 150 | path = Category; 151 | sourceTree = ""; 152 | }; 153 | 4373F05423FE6A6D003A51A2 /* Config */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 4373F06423FE72E5003A51A2 /* RCCellConfig.h */, 157 | 4373F06523FE72E5003A51A2 /* RCCellConfig.m */, 158 | 4373F06723FE72FD003A51A2 /* RCSection.h */, 159 | 4373F06823FE72FD003A51A2 /* RCSection.m */, 160 | 4373F06A23FE7313003A51A2 /* RCHeaderFooterConfig.h */, 161 | 4373F06B23FE7313003A51A2 /* RCHeaderFooterConfig.m */, 162 | ); 163 | path = Config; 164 | sourceTree = ""; 165 | }; 166 | 4373F05623FE6A6D003A51A2 /* Protocol */ = { 167 | isa = PBXGroup; 168 | children = ( 169 | 4373F06023FE71F5003A51A2 /* RCCellProtocol.h */, 170 | 4373F06123FE7202003A51A2 /* RCHeaderFooterProtocol.h */, 171 | 4373F06223FE722B003A51A2 /* RCCellConfigProtocol.h */, 172 | 4373F06323FE723B003A51A2 /* RCHeaderFooterConfigProtocol.h */, 173 | ); 174 | path = Protocol; 175 | sourceTree = ""; 176 | }; 177 | 4373F06D23FE775C003A51A2 /* Implement */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 4373F06E23FE7777003A51A2 /* RCTableViewImplement.h */, 181 | 4373F06F23FE7777003A51A2 /* RCTableViewImplement.m */, 182 | 4373F07123FE7783003A51A2 /* RCCollectionViewImplement.h */, 183 | 4373F07223FE7783003A51A2 /* RCCollectionViewImplement.m */, 184 | ); 185 | path = Implement; 186 | sourceTree = ""; 187 | }; 188 | 4373F07423FE84FE003A51A2 /* Example */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | 4373F07523FE84FE003A51A2 /* ViewController.m */, 192 | 4373F07623FE84FE003A51A2 /* ViewController.h */, 193 | 4373F08023FE8565003A51A2 /* ExampleModel.h */, 194 | 4373F08123FE8565003A51A2 /* ExampleModel.m */, 195 | 4373F08323FE8579003A51A2 /* ExampleTableViewCell.h */, 196 | 4373F08423FE8579003A51A2 /* ExampleTableViewCell.m */, 197 | 4373F08823FE8C99003A51A2 /* ExampleDataManager.h */, 198 | 4373F08923FE8C99003A51A2 /* ExampleDataManager.m */, 199 | ); 200 | path = Example; 201 | sourceTree = ""; 202 | }; 203 | /* End PBXGroup section */ 204 | 205 | /* Begin PBXNativeTarget section */ 206 | 4373F03323FE69C4003A51A2 /* ForwardProxy */ = { 207 | isa = PBXNativeTarget; 208 | buildConfigurationList = 4373F04D23FE69C6003A51A2 /* Build configuration list for PBXNativeTarget "ForwardProxy" */; 209 | buildPhases = ( 210 | 4373F03023FE69C4003A51A2 /* Sources */, 211 | 4373F03123FE69C4003A51A2 /* Frameworks */, 212 | 4373F03223FE69C4003A51A2 /* Resources */, 213 | ); 214 | buildRules = ( 215 | ); 216 | dependencies = ( 217 | ); 218 | name = ForwardProxy; 219 | productName = ForwardProxy; 220 | productReference = 4373F03423FE69C4003A51A2 /* ForwardProxy.app */; 221 | productType = "com.apple.product-type.application"; 222 | }; 223 | /* End PBXNativeTarget section */ 224 | 225 | /* Begin PBXProject section */ 226 | 4373F02C23FE69C4003A51A2 /* Project object */ = { 227 | isa = PBXProject; 228 | attributes = { 229 | LastUpgradeCheck = 1130; 230 | ORGANIZATIONNAME = linitial; 231 | TargetAttributes = { 232 | 4373F03323FE69C4003A51A2 = { 233 | CreatedOnToolsVersion = 11.3.1; 234 | }; 235 | }; 236 | }; 237 | buildConfigurationList = 4373F02F23FE69C4003A51A2 /* Build configuration list for PBXProject "ForwardProxy" */; 238 | compatibilityVersion = "Xcode 9.3"; 239 | developmentRegion = en; 240 | hasScannedForEncodings = 0; 241 | knownRegions = ( 242 | en, 243 | Base, 244 | ); 245 | mainGroup = 4373F02B23FE69C4003A51A2; 246 | productRefGroup = 4373F03523FE69C4003A51A2 /* Products */; 247 | projectDirPath = ""; 248 | projectRoot = ""; 249 | targets = ( 250 | 4373F03323FE69C4003A51A2 /* ForwardProxy */, 251 | ); 252 | }; 253 | /* End PBXProject section */ 254 | 255 | /* Begin PBXResourcesBuildPhase section */ 256 | 4373F03223FE69C4003A51A2 /* Resources */ = { 257 | isa = PBXResourcesBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | 4373F04723FE69C6003A51A2 /* LaunchScreen.storyboard in Resources */, 261 | 4373F04423FE69C6003A51A2 /* Assets.xcassets in Resources */, 262 | 4373F04223FE69C4003A51A2 /* Main.storyboard in Resources */, 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | /* End PBXResourcesBuildPhase section */ 267 | 268 | /* Begin PBXSourcesBuildPhase section */ 269 | 4373F03023FE69C4003A51A2 /* Sources */ = { 270 | isa = PBXSourcesBuildPhase; 271 | buildActionMask = 2147483647; 272 | files = ( 273 | 4373F03923FE69C4003A51A2 /* AppDelegate.m in Sources */, 274 | 4373F05923FE6A8B003A51A2 /* RCProxy.m in Sources */, 275 | 4373F04A23FE69C6003A51A2 /* main.m in Sources */, 276 | 4373F06623FE72E5003A51A2 /* RCCellConfig.m in Sources */, 277 | 4373F07023FE7777003A51A2 /* RCTableViewImplement.m in Sources */, 278 | 4373F07723FE84FE003A51A2 /* ViewController.m in Sources */, 279 | 4373F05F23FE718D003A51A2 /* UIScrollView+Addition.m in Sources */, 280 | 4373F06C23FE7313003A51A2 /* RCHeaderFooterConfig.m in Sources */, 281 | 4373F05C23FE6ADB003A51A2 /* NSObject+Next.m in Sources */, 282 | 4373F08223FE8565003A51A2 /* ExampleModel.m in Sources */, 283 | 4373F08623FE8579003A51A2 /* ExampleTableViewCell.m in Sources */, 284 | CEFE2EF124EB704800CC9AB3 /* NSObject+MutiplyProxy.m in Sources */, 285 | 4373F08A23FE8C99003A51A2 /* ExampleDataManager.m in Sources */, 286 | 4373F07323FE7783003A51A2 /* RCCollectionViewImplement.m in Sources */, 287 | 4373F03C23FE69C4003A51A2 /* SceneDelegate.m in Sources */, 288 | 4373F06923FE72FD003A51A2 /* RCSection.m in Sources */, 289 | ); 290 | runOnlyForDeploymentPostprocessing = 0; 291 | }; 292 | /* End PBXSourcesBuildPhase section */ 293 | 294 | /* Begin PBXVariantGroup section */ 295 | 4373F04023FE69C4003A51A2 /* Main.storyboard */ = { 296 | isa = PBXVariantGroup; 297 | children = ( 298 | 4373F04123FE69C4003A51A2 /* Base */, 299 | ); 300 | name = Main.storyboard; 301 | sourceTree = ""; 302 | }; 303 | 4373F04523FE69C6003A51A2 /* LaunchScreen.storyboard */ = { 304 | isa = PBXVariantGroup; 305 | children = ( 306 | 4373F04623FE69C6003A51A2 /* Base */, 307 | ); 308 | name = LaunchScreen.storyboard; 309 | sourceTree = ""; 310 | }; 311 | /* End PBXVariantGroup section */ 312 | 313 | /* Begin XCBuildConfiguration section */ 314 | 4373F04B23FE69C6003A51A2 /* Debug */ = { 315 | isa = XCBuildConfiguration; 316 | buildSettings = { 317 | ALWAYS_SEARCH_USER_PATHS = NO; 318 | CLANG_ANALYZER_NONNULL = YES; 319 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 320 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 321 | CLANG_CXX_LIBRARY = "libc++"; 322 | CLANG_ENABLE_MODULES = YES; 323 | CLANG_ENABLE_OBJC_ARC = YES; 324 | CLANG_ENABLE_OBJC_WEAK = YES; 325 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 326 | CLANG_WARN_BOOL_CONVERSION = YES; 327 | CLANG_WARN_COMMA = YES; 328 | CLANG_WARN_CONSTANT_CONVERSION = YES; 329 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 330 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 331 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 332 | CLANG_WARN_EMPTY_BODY = YES; 333 | CLANG_WARN_ENUM_CONVERSION = YES; 334 | CLANG_WARN_INFINITE_RECURSION = YES; 335 | CLANG_WARN_INT_CONVERSION = YES; 336 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 337 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 338 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 339 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 340 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 341 | CLANG_WARN_STRICT_PROTOTYPES = YES; 342 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 343 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 344 | CLANG_WARN_UNREACHABLE_CODE = YES; 345 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 346 | COPY_PHASE_STRIP = NO; 347 | DEBUG_INFORMATION_FORMAT = dwarf; 348 | ENABLE_STRICT_OBJC_MSGSEND = YES; 349 | ENABLE_TESTABILITY = YES; 350 | GCC_C_LANGUAGE_STANDARD = gnu11; 351 | GCC_DYNAMIC_NO_PIC = NO; 352 | GCC_NO_COMMON_BLOCKS = YES; 353 | GCC_OPTIMIZATION_LEVEL = 0; 354 | GCC_PREPROCESSOR_DEFINITIONS = ( 355 | "DEBUG=1", 356 | "$(inherited)", 357 | ); 358 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 359 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 360 | GCC_WARN_UNDECLARED_SELECTOR = YES; 361 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 362 | GCC_WARN_UNUSED_FUNCTION = YES; 363 | GCC_WARN_UNUSED_VARIABLE = YES; 364 | IPHONEOS_DEPLOYMENT_TARGET = 13.2; 365 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 366 | MTL_FAST_MATH = YES; 367 | ONLY_ACTIVE_ARCH = YES; 368 | SDKROOT = iphoneos; 369 | }; 370 | name = Debug; 371 | }; 372 | 4373F04C23FE69C6003A51A2 /* Release */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | ALWAYS_SEARCH_USER_PATHS = NO; 376 | CLANG_ANALYZER_NONNULL = YES; 377 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 378 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 379 | CLANG_CXX_LIBRARY = "libc++"; 380 | CLANG_ENABLE_MODULES = YES; 381 | CLANG_ENABLE_OBJC_ARC = YES; 382 | CLANG_ENABLE_OBJC_WEAK = YES; 383 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 384 | CLANG_WARN_BOOL_CONVERSION = YES; 385 | CLANG_WARN_COMMA = YES; 386 | CLANG_WARN_CONSTANT_CONVERSION = YES; 387 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 388 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 389 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 390 | CLANG_WARN_EMPTY_BODY = YES; 391 | CLANG_WARN_ENUM_CONVERSION = YES; 392 | CLANG_WARN_INFINITE_RECURSION = YES; 393 | CLANG_WARN_INT_CONVERSION = YES; 394 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 395 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 396 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 397 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 398 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 399 | CLANG_WARN_STRICT_PROTOTYPES = YES; 400 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 401 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 402 | CLANG_WARN_UNREACHABLE_CODE = YES; 403 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 404 | COPY_PHASE_STRIP = NO; 405 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 406 | ENABLE_NS_ASSERTIONS = NO; 407 | ENABLE_STRICT_OBJC_MSGSEND = YES; 408 | GCC_C_LANGUAGE_STANDARD = gnu11; 409 | GCC_NO_COMMON_BLOCKS = YES; 410 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 411 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 412 | GCC_WARN_UNDECLARED_SELECTOR = YES; 413 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 414 | GCC_WARN_UNUSED_FUNCTION = YES; 415 | GCC_WARN_UNUSED_VARIABLE = YES; 416 | IPHONEOS_DEPLOYMENT_TARGET = 13.2; 417 | MTL_ENABLE_DEBUG_INFO = NO; 418 | MTL_FAST_MATH = YES; 419 | SDKROOT = iphoneos; 420 | VALIDATE_PRODUCT = YES; 421 | }; 422 | name = Release; 423 | }; 424 | 4373F04E23FE69C6003A51A2 /* Debug */ = { 425 | isa = XCBuildConfiguration; 426 | buildSettings = { 427 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 428 | CODE_SIGN_STYLE = Automatic; 429 | INFOPLIST_FILE = ForwardProxy/Info.plist; 430 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 431 | LD_RUNPATH_SEARCH_PATHS = ( 432 | "$(inherited)", 433 | "@executable_path/Frameworks", 434 | ); 435 | PRODUCT_BUNDLE_IDENTIFIER = com.linitial.ForwardProxy; 436 | PRODUCT_NAME = "$(TARGET_NAME)"; 437 | TARGETED_DEVICE_FAMILY = 1; 438 | }; 439 | name = Debug; 440 | }; 441 | 4373F04F23FE69C6003A51A2 /* Release */ = { 442 | isa = XCBuildConfiguration; 443 | buildSettings = { 444 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 445 | CODE_SIGN_STYLE = Automatic; 446 | INFOPLIST_FILE = ForwardProxy/Info.plist; 447 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 448 | LD_RUNPATH_SEARCH_PATHS = ( 449 | "$(inherited)", 450 | "@executable_path/Frameworks", 451 | ); 452 | PRODUCT_BUNDLE_IDENTIFIER = com.linitial.ForwardProxy; 453 | PRODUCT_NAME = "$(TARGET_NAME)"; 454 | TARGETED_DEVICE_FAMILY = 1; 455 | }; 456 | name = Release; 457 | }; 458 | /* End XCBuildConfiguration section */ 459 | 460 | /* Begin XCConfigurationList section */ 461 | 4373F02F23FE69C4003A51A2 /* Build configuration list for PBXProject "ForwardProxy" */ = { 462 | isa = XCConfigurationList; 463 | buildConfigurations = ( 464 | 4373F04B23FE69C6003A51A2 /* Debug */, 465 | 4373F04C23FE69C6003A51A2 /* Release */, 466 | ); 467 | defaultConfigurationIsVisible = 0; 468 | defaultConfigurationName = Release; 469 | }; 470 | 4373F04D23FE69C6003A51A2 /* Build configuration list for PBXNativeTarget "ForwardProxy" */ = { 471 | isa = XCConfigurationList; 472 | buildConfigurations = ( 473 | 4373F04E23FE69C6003A51A2 /* Debug */, 474 | 4373F04F23FE69C6003A51A2 /* Release */, 475 | ); 476 | defaultConfigurationIsVisible = 0; 477 | defaultConfigurationName = Release; 478 | }; 479 | /* End XCConfigurationList section */ 480 | }; 481 | rootObject = 4373F02C23FE69C4003A51A2 /* Project object */; 482 | } 483 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy.xcodeproj/project.xcworkspace/xcuserdata/linitial.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecheLi/ForwardProxy/1d7941f9234a6114c624d54a73ebc1b858fb0eb9/ForwardProxy/ForwardProxy.xcodeproj/project.xcworkspace/xcuserdata/linitial.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy.xcodeproj/xcuserdata/linitial.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 21 | 22 | 23 | 25 | 37 | 38 | 39 | 41 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy.xcodeproj/xcuserdata/linitial.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ForwardProxy.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecheLi/ForwardProxy/1d7941f9234a6114c624d54a73ebc1b858fb0eb9/ForwardProxy/ForwardProxy/.DS_Store -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2020/01/20. 6 | // Copyright © 2020 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2020/01/20. 6 | // Copyright © 2020 linitial. 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 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/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 | } -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/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 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/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 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/Example/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecheLi/ForwardProxy/1d7941f9234a6114c624d54a73ebc1b858fb0eb9/ForwardProxy/ForwardProxy/Example/.DS_Store -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/Example/ExampleDataManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleDataManager.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ExampleModel.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @class RCSection; 15 | 16 | @interface ExampleDataManager : NSObject 17 | 18 | - (void)getDataComletion:(void(^)(NSArray *sections))completion; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/Example/ExampleDataManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleDataManager.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "ExampleDataManager.h" 10 | #import "ExampleTableViewCell.h" 11 | #import "UIScrollView+Addition.h" 12 | 13 | @interface ExampleDataManager () 14 | 15 | @end 16 | 17 | @implementation ExampleDataManager 18 | 19 | - (void)getDataComletion:(void(^)(NSArray *sections))completion { 20 | RCSection *section = [RCSection new]; 21 | NSMutableArray *configs = @[].mutableCopy; 22 | for (int i=0; i<10; i++) { 23 | ExampleModel *model = [self createExampleModelWithIndex:i]; 24 | RCCellConfig *config = [[RCCellConfig alloc]init]; 25 | config.model = model; 26 | config.cellClass = [ExampleTableViewCell class]; 27 | config.itemSize = CGSizeZero; 28 | [configs addObject:config]; 29 | } 30 | section.configs = configs; 31 | if (completion) { 32 | completion(@[section]); 33 | } 34 | } 35 | 36 | - (ExampleModel *)createExampleModelWithIndex:(NSInteger)index { 37 | ExampleModel *model = [ExampleModel new]; 38 | model.title = [NSString stringWithFormat:@"这是第%@个 title",@(index)]; 39 | model.detail = [NSString stringWithFormat:@"这是第%@个 detail",@(index)]; 40 | return model; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/Example/ExampleModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleModel.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ExampleModel : NSObject 14 | 15 | @property (nonatomic, copy) NSString *title; 16 | 17 | @property (nonatomic, copy) NSString *detail; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/Example/ExampleModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleModel.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "ExampleModel.h" 10 | 11 | @implementation ExampleModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/Example/ExampleTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleTableViewCell.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RCCellProtocol.h" 11 | #import "RCCellConfigProtocol.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface ExampleTableViewCell : UITableViewCell 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/Example/ExampleTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleTableViewCell.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "ExampleTableViewCell.h" 10 | #import "ExampleModel.h" 11 | #import "RCCellConfig.h" 12 | 13 | @interface ExampleTableViewCell () 14 | 15 | @property (nonatomic, strong) UILabel *titleLabel; 16 | 17 | @property (nonatomic, strong) UILabel *detailLabel; 18 | 19 | @property (nonatomic, strong) ExampleModel *exampleModel; 20 | 21 | @end 22 | 23 | @implementation ExampleTableViewCell 24 | 25 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 26 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 27 | if (self) { 28 | [self.contentView addSubview:self.titleLabel]; 29 | [self.contentView addSubview:self.detailLabel]; 30 | } 31 | return self; 32 | } 33 | 34 | 35 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 36 | [super setSelected:selected animated:animated]; 37 | 38 | // Configure the view for the selected state 39 | } 40 | 41 | - (void)setExampleModel:(ExampleModel *)exampleModel { 42 | _exampleModel = exampleModel; 43 | _detailLabel.text = _exampleModel.detail; 44 | _titleLabel.text = _exampleModel.title; 45 | } 46 | 47 | #pragma mark - RCCellProtocol 48 | - (void)rc_setCellConfig:(id)cellConfig { 49 | RCCellConfig *config = (RCCellConfig *)cellConfig; 50 | self.exampleModel = (ExampleModel *)config.model; 51 | } 52 | 53 | + (CGSize)rc_sizeForCellWithConfig:(id)cellConfig atIndexPath:(nullable NSIndexPath *)indexPath { 54 | return CGSizeMake([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height*0.25); 55 | } 56 | 57 | - (void)rc_didSelectCellAtIndexPath:(NSIndexPath *)indexPath { 58 | NSLog(@"clicked indexpath : %@",indexPath); 59 | } 60 | 61 | #pragma mark - Getter 62 | - (UILabel *)titleLabel { 63 | if (!_titleLabel) { 64 | _titleLabel = [UILabel new]; 65 | _titleLabel.textColor = [UIColor blackColor]; 66 | _titleLabel.font = [UIFont systemFontOfSize:17]; 67 | _titleLabel.frame = CGRectMake(10, 0, 200, 100); 68 | } 69 | return _titleLabel; 70 | } 71 | 72 | - (UILabel *)detailLabel { 73 | if (!_detailLabel) { 74 | _detailLabel = [UILabel new]; 75 | _detailLabel.textColor = [UIColor grayColor]; 76 | _detailLabel.font = [UIFont systemFontOfSize:14]; 77 | _detailLabel.frame = CGRectMake(10, 110, 200, 100); 78 | } 79 | return _detailLabel; 80 | } 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/Example/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2020/01/20. 6 | // Copyright © 2020 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/Example/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2020/01/20. 6 | // Copyright © 2020 linitial. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "UIScrollView+Addition.h" 11 | #import "ExampleDataManager.h" 12 | 13 | @interface ViewController () 14 | 15 | @property (nonatomic, strong) UITableView *tableView; 16 | 17 | @property (nonatomic, strong) ExampleDataManager *dataManager; 18 | @end 19 | 20 | @implementation ViewController 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | [self.view addSubview:self.tableView]; 25 | [self.tableView rc_addDelegate:self]; 26 | [self _getData]; 27 | } 28 | 29 | - (void)_getData { 30 | __weak typeof(self)weakSelf = self; 31 | [self.dataManager getDataComletion:^(NSArray * _Nonnull sections) { 32 | __strong typeof(weakSelf) strongSelf = weakSelf; 33 | strongSelf.tableView.rc_sections = sections; 34 | }]; 35 | } 36 | 37 | #pragma mark - Getter 38 | - (ExampleDataManager *)dataManager { 39 | if (!_dataManager) { 40 | _dataManager = [ExampleDataManager new]; 41 | } 42 | return _dataManager; 43 | } 44 | 45 | - (UITableView *)tableView { 46 | if (!_tableView) { 47 | _tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) style:UITableViewStylePlain]; 48 | } 49 | return _tableView; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecheLi/ForwardProxy/1d7941f9234a6114c624d54a73ebc1b858fb0eb9/ForwardProxy/ForwardProxy/ForwadProxy/.DS_Store -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Category/NSObject+MutiplyProxy.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MutiplyProxy.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2020/08/18. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RCProxy.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface NSObject (MutiplyProxy) 15 | 16 | @property (nonatomic, strong) RCProxy *rcProxy; 17 | 18 | - (void)bindProxies:(NSArray *)proxies; 19 | - (void)bindProxy:(id)proxy; 20 | - (void)removeProxy:(id)proxy; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Category/NSObject+MutiplyProxy.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MutiplyProxy.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2020/08/18. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "NSObject+MutiplyProxy.h" 10 | #import 11 | 12 | static void bind_proxy_in_main_thread_safely(dispatch_block_t block) { 13 | if (![[NSThread currentThread]isMainThread]) { 14 | dispatch_async(dispatch_get_main_queue(),^{ 15 | block(); 16 | }); 17 | return; 18 | } 19 | block(); 20 | } 21 | 22 | @interface NSObject () 23 | 24 | @end 25 | 26 | static void *kMutiplyProxy = &kMutiplyProxy; 27 | 28 | @implementation NSObject (MutiplyProxy) 29 | 30 | - (void)bindProxies:(NSArray *)proxies { 31 | bind_proxy_in_main_thread_safely(^{ 32 | if (proxies.count==0) return; 33 | for (id proxy in proxies) { 34 | [self.rcProxy addTarget:proxy]; 35 | } 36 | }); 37 | } 38 | 39 | - (void)bindProxy:(id)proxy { 40 | bind_proxy_in_main_thread_safely(^{ 41 | [self.rcProxy addTarget:proxy]; 42 | }); 43 | } 44 | 45 | - (void)removeProxy:(id)proxy { 46 | bind_proxy_in_main_thread_safely(^{ 47 | [self.rcProxy removeTarget:proxy]; 48 | }); 49 | } 50 | 51 | - (void)setRcProxy:(RCProxy *)rcProxy { 52 | objc_setAssociatedObject(self, kMutiplyProxy, rcProxy, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 53 | } 54 | 55 | - (RCProxy *)rcProxy { 56 | RCProxy *proxy = objc_getAssociatedObject(self, kMutiplyProxy); 57 | if (!proxy) { 58 | proxy = [[RCProxy alloc]initProxy]; 59 | self.rcProxy = proxy; 60 | } 61 | return proxy; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Category/NSObject+Next.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Next.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface NSObject (Next) 15 | 16 | - (id)then:(void(^)(id v))next; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Category/NSObject+Next.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Next.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "NSObject+Next.h" 10 | 11 | @implementation NSObject (Next) 12 | 13 | - (id)then:(void(^)(id v))next { 14 | next(self); 15 | return self; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Category/UIScrollView+Addition.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+Addition.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RCCellProtocol.h" 11 | #import "RCCellConfig.h" 12 | #import "RCHeaderFooterConfig.h" 13 | #import "RCHeaderFooterConfigProtocol.h" 14 | #import "RCSection.h" 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | @interface UIScrollView (Addition) 19 | 20 | // 配置数组 21 | @property (nonatomic, copy, nullable) NSArray *rc_sections; 22 | 23 | // 只有一个section的情况可以用 24 | @property (nonatomic, copy, nullable) NSArray> *rc_singleConfigs; 25 | 26 | // cellForItemAtIndexPath 回调 27 | @property (nonatomic, copy, nullable) void(^rc_refreshCellBlock)(UIView *cell, NSIndexPath *indexPath); 28 | 29 | // didSelectItemAtIndexPath 回调 30 | @property (nonatomic, copy, nullable) void(^rc_didSelectCellBlock)(UIView *cell, NSIndexPath *indexPath); 31 | 32 | // 刷新头部 回调 33 | @property (nonatomic, copy, nullable) void(^rc_refreshHeaderBlock)(UIView *header, NSIndexPath *indexPath); 34 | 35 | // 刷新尾部 回调 36 | @property (nonatomic, copy, nullable) void(^rc_refresrcooterBlock)(UIView *footer, NSIndexPath *indexPath); 37 | 38 | // willDisplayCell 回调 39 | @property (nonatomic, copy, nullable) void(^rc_willDisplayCellBlock)(UIView *cell, NSIndexPath *indexPath); 40 | 41 | // didEndDisplayingCell 回调 42 | @property (nonatomic, copy, nullable) void(^rc_didEndDisplayingCellBlock)(UIView *cell, NSIndexPath *indexPath); 43 | 44 | - (void)rc_addDelegate:(id)delegate; 45 | - (void)rc_addDataSource:(id)dataSource; 46 | 47 | @end 48 | 49 | NS_ASSUME_NONNULL_END 50 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Category/UIScrollView+Addition.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+Addition.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "UIScrollView+Addition.h" 10 | #import 11 | #import "RCTableViewImplement.h" 12 | #import "RCCollectionViewImplement.h" 13 | #import "RCProxy.h" 14 | 15 | static const void *kRCSectionsKey = &kRCSectionsKey; 16 | static const void *kTVBForwardProxyKey = &kTVBForwardProxyKey; 17 | static const void *kRCIMPKey = &kRCIMPKey; 18 | static const void *kRCRefreshCellBlockKey = &kRCRefreshCellBlockKey; 19 | static const void *kRCDidSelectCellBlockKey = &kRCDidSelectCellBlockKey; 20 | static const void *kRCRefreshHeaderBlockKey = &kRCRefreshHeaderBlockKey; 21 | static const void *kRCRefresrcooterBlockKey = &kRCRefresrcooterBlockKey; 22 | static const void *kRCWillDispalyCellBlockKey = &kRCWillDispalyCellBlockKey; 23 | static const void *kRCDidEndDispalyingCellBlockKey = &kRCDidEndDispalyingCellBlockKey; 24 | 25 | @interface UIScrollView () 26 | 27 | @property (nonatomic, strong) RCProxy *rcProxy; 28 | 29 | @property (nonatomic, strong) RCTableViewImplement *tableViewImp; 30 | 31 | @property (nonatomic, strong) RCCollectionViewImplement *collectionViewImp; 32 | @end 33 | 34 | @implementation UIScrollView (Addition) 35 | 36 | static void rc_dispatch_main_async_safely(dispatch_block_t block) { 37 | if ([[NSThread currentThread]isMainThread]) { 38 | block(); 39 | } else { 40 | dispatch_async(dispatch_get_main_queue(), block); 41 | } 42 | } 43 | 44 | - (void)rc_asycBuildSections:(NSArray *(^)(void))buildBlock 45 | onMainLoopCompletion:(void(^)(void))completion { 46 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 47 | NSArray *sections = buildBlock(); 48 | dispatch_async(dispatch_get_main_queue(), ^{ 49 | self.rc_sections = sections; 50 | if (completion) { 51 | completion(); 52 | } 53 | }); 54 | }); 55 | } 56 | 57 | - (void)rc_addObjectsFromSections:(NSArray *)sections { 58 | rc_dispatch_main_async_safely(^{ 59 | [self rc_registerClassForSections:sections]; 60 | NSMutableArray *rc_sections = [NSMutableArray arrayWithArray:self.rc_sections]; 61 | [rc_sections addObjectsFromArray:sections]; 62 | NSArray *rc_arr = [rc_sections copy]; 63 | objc_setAssociatedObject(self, kRCSectionsKey, rc_arr, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 64 | if ([self isKindOfClass:[UITableView class]]) { 65 | self.tableViewImp.sections = rc_arr; 66 | } 67 | if ([self isKindOfClass:[UICollectionView class]]) { 68 | self.collectionViewImp.sections = rc_arr; 69 | } 70 | }); 71 | } 72 | 73 | - (void)rc_deleteSectionAtIndex:(NSInteger)index { 74 | rc_dispatch_main_async_safely(^{ 75 | NSMutableArray *rc_sections = [NSMutableArray arrayWithArray:self.rc_sections]; 76 | [rc_sections removeObjectAtIndex:index]; 77 | NSArray *rc_arr = [rc_sections copy]; 78 | objc_setAssociatedObject(self, kRCSectionsKey, rc_arr, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 79 | if ([self isKindOfClass:[UITableView class]]) { 80 | self.tableViewImp.sections = rc_arr; 81 | } 82 | if ([self isKindOfClass:[UICollectionView class]]) { 83 | self.collectionViewImp.sections = rc_arr; 84 | } 85 | }); 86 | } 87 | 88 | - (void)rc_insertSection:(RCSection *)secton atIndex:(NSInteger)index { 89 | rc_dispatch_main_async_safely(^{ 90 | [self rc_registerClassForSections:@[secton]]; 91 | NSMutableArray *rc_sections = [NSMutableArray arrayWithArray:self.rc_sections]; 92 | [rc_sections insertObject:secton atIndex:index]; 93 | NSArray *rc_arr = [rc_sections copy]; 94 | objc_setAssociatedObject(self, kRCSectionsKey, rc_arr, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 95 | if ([self isKindOfClass:[UITableView class]]) { 96 | self.tableViewImp.sections = rc_arr; 97 | } 98 | if ([self isKindOfClass:[UICollectionView class]]) { 99 | self.collectionViewImp.sections = rc_arr; 100 | } 101 | }); 102 | } 103 | 104 | - (void)rc_replaceSection:(RCSection *)secton atIndex:(NSInteger)index { 105 | rc_dispatch_main_async_safely(^{ 106 | [self rc_registerClassForSections:@[secton]]; 107 | NSMutableArray *rc_sections = [NSMutableArray arrayWithArray:self.rc_sections]; 108 | [rc_sections replaceObjectAtIndex:index withObject:secton]; 109 | NSArray *rc_arr = [rc_sections copy]; 110 | objc_setAssociatedObject(self, kRCSectionsKey, rc_arr, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 111 | if ([self isKindOfClass:[UITableView class]]) { 112 | self.tableViewImp.sections = rc_arr; 113 | } 114 | if ([self isKindOfClass:[UICollectionView class]]) { 115 | self.collectionViewImp.sections = rc_arr; 116 | } 117 | }); 118 | } 119 | 120 | - (void)rc_addDelegate:(id)delegate { 121 | [self.rcProxy addTarget:delegate]; 122 | } 123 | 124 | - (void)rc_addDataSource:(id)dataSource { 125 | [self.rcProxy addTarget:dataSource]; 126 | } 127 | 128 | - (void)rc_bindCellDelegate:(id)cellDelegate { 129 | if ([self isKindOfClass:[UITableView class]]) { 130 | self.tableViewImp.cellDelegate = cellDelegate; 131 | } 132 | if ([self isKindOfClass:[UICollectionView class]]) { 133 | self.collectionViewImp.cellDelegate = cellDelegate; 134 | } 135 | } 136 | 137 | - (void)rc_registerClassForSections:(NSArray *)sections { 138 | if ([self isKindOfClass:[UITableView class]]) { 139 | UITableView *tableViewSelf = (UITableView *)self; 140 | for (RCSection *section in sections) { 141 | for (id config in section.configs) { 142 | [tableViewSelf registerClass:config.rc_cellClass forCellReuseIdentifier:[self reuseIdentifierForCellConfig:config]]; 143 | } 144 | id headerConfig = section.header; 145 | if (headerConfig) { 146 | [tableViewSelf registerClass:headerConfig.rc_headerFooterClass forHeaderFooterViewReuseIdentifier:[self reuseIdentifierForHeaderFooterConfig:headerConfig]]; 147 | } 148 | id footerConfig = section.footer; 149 | if (footerConfig) { 150 | [tableViewSelf registerClass:footerConfig.rc_headerFooterClass forHeaderFooterViewReuseIdentifier:[self reuseIdentifierForHeaderFooterConfig:footerConfig]]; 151 | } 152 | } 153 | [tableViewSelf registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([UITableViewCell class])]; 154 | } 155 | if ([self isKindOfClass:[UICollectionView class]]) { 156 | UICollectionView *collectionViewSelf = (UICollectionView *)self; 157 | for (RCSection *section in sections) { 158 | for (id config in section.configs) { 159 | [collectionViewSelf registerClass:config.rc_cellClass forCellWithReuseIdentifier:[self reuseIdentifierForCellConfig:config]]; 160 | } 161 | id headerConfig = section.header; 162 | if (headerConfig) { 163 | [collectionViewSelf registerClass:headerConfig.rc_headerFooterClass forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:[self reuseIdentifierForHeaderFooterConfig:headerConfig]]; 164 | } 165 | 166 | id footerConfig = section.footer; 167 | if (footerConfig) { 168 | [collectionViewSelf registerClass:footerConfig.rc_headerFooterClass forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:[self reuseIdentifierForHeaderFooterConfig:footerConfig]]; 169 | } 170 | } 171 | [collectionViewSelf registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class])]; 172 | } 173 | } 174 | 175 | #pragma mark - Getter & Setter 176 | 177 | - (void)setRc_singleConfigs:(NSArray> *)rc_singleConfigs { 178 | RCSection *section = [[RCSection alloc] init]; 179 | section.configs = rc_singleConfigs; 180 | 181 | self.rc_sections = @[section]; 182 | } 183 | 184 | - (NSArray> *)rc_singleConfigs { 185 | return self.rc_sections.firstObject.configs; 186 | } 187 | 188 | - (void)setRc_sections:(NSArray *)rc_sections { 189 | if (!rc_sections) { 190 | rc_sections = @[]; 191 | } 192 | objc_setAssociatedObject(self, kRCSectionsKey, rc_sections, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 193 | __weak typeof(self) weakSelf =self; 194 | rc_dispatch_main_async_safely(^{ 195 | __strong typeof(weakSelf) strongSelf = weakSelf; 196 | if ([strongSelf isKindOfClass:[UITableView class]]) { 197 | strongSelf.tableViewImp.sections = rc_sections; 198 | [strongSelf.rcProxy addTarget:strongSelf.tableViewImp]; 199 | UITableView *tableViewSelf = (UITableView *)strongSelf; 200 | tableViewSelf.delegate = (id)strongSelf.rcProxy; 201 | tableViewSelf.dataSource = (id)strongSelf.rcProxy; 202 | } 203 | if ([strongSelf isKindOfClass:[UICollectionView class]]) { 204 | strongSelf.collectionViewImp.sections = rc_sections; 205 | [strongSelf.rcProxy addTarget:strongSelf.collectionViewImp]; 206 | UICollectionView *collectionViewSelf = (UICollectionView *)strongSelf; 207 | collectionViewSelf.delegate = (id)strongSelf.rcProxy; 208 | collectionViewSelf.dataSource = (id)strongSelf.rcProxy; 209 | } 210 | [self rc_registerClassForSections:rc_sections]; 211 | }); 212 | } 213 | 214 | - (NSArray *)rc_sections { 215 | return objc_getAssociatedObject(self, kRCSectionsKey); 216 | } 217 | 218 | - (void)setRcProxy:(RCProxy *)rcProxy { 219 | objc_setAssociatedObject(self, kTVBForwardProxyKey, rcProxy, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 220 | } 221 | 222 | - (RCProxy *)rcProxy { 223 | RCProxy *proxy = objc_getAssociatedObject(self, kTVBForwardProxyKey); 224 | if (!proxy) { 225 | proxy = [[RCProxy alloc]initProxy]; 226 | self.rcProxy = proxy; 227 | } 228 | return proxy; 229 | } 230 | 231 | - (void)setTableViewIMP:(RCTableViewImplement *)tableViewImp { 232 | objc_setAssociatedObject(self, kRCIMPKey, tableViewImp, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 233 | } 234 | 235 | - (RCTableViewImplement *)tableViewImp { 236 | RCTableViewImplement *imp = objc_getAssociatedObject(self, kRCIMPKey); 237 | if (!imp) { 238 | imp = [[RCTableViewImplement alloc] init]; 239 | self.tableViewIMP = imp; 240 | } 241 | return imp; 242 | } 243 | 244 | - (void)setCollectionViewIMP:(RCCollectionViewImplement *)collectionViewImp { 245 | objc_setAssociatedObject(self, kRCIMPKey, collectionViewImp, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 246 | } 247 | 248 | - (RCCollectionViewImplement *)collectionViewImp { 249 | RCCollectionViewImplement *imp = objc_getAssociatedObject(self, kRCIMPKey); 250 | if (!imp) { 251 | imp = [[RCCollectionViewImplement alloc] init]; 252 | self.collectionViewImp = imp; 253 | } 254 | return imp; 255 | } 256 | 257 | - (void)setRc_refreshCellBlock:(void (^)(UIView * _Nonnull, NSIndexPath * _Nonnull))rc_refreshCellBlock { 258 | objc_setAssociatedObject(self, kRCRefreshCellBlockKey, rc_refreshCellBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); 259 | } 260 | 261 | - (void (^)(UIView *, NSIndexPath *))rc_refreshCellBlock { 262 | return objc_getAssociatedObject(self, kRCRefreshCellBlockKey); 263 | } 264 | 265 | - (void)setRc_didSelectCellBlock:(void (^)(UIView *, NSIndexPath *))rc_didSelectCellBlock { 266 | objc_setAssociatedObject(self, kRCDidSelectCellBlockKey, rc_didSelectCellBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); 267 | } 268 | 269 | - (void (^)(UIView *, NSIndexPath *))rc_didSelectCellBlock { 270 | return objc_getAssociatedObject(self, kRCDidSelectCellBlockKey); 271 | } 272 | 273 | - (void)setRc_refreshHeaderBlock:(void (^)(UIView *, NSIndexPath *))rc_refreshHeaderBlock { 274 | objc_setAssociatedObject(self, kRCRefreshHeaderBlockKey, rc_refreshHeaderBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); 275 | } 276 | 277 | - (void (^)(UIView *, NSIndexPath *))rc_refreshHeaderBlock { 278 | return objc_getAssociatedObject(self, kRCRefreshHeaderBlockKey); 279 | } 280 | 281 | - (void)setRc_refresrcooterBlock:(void (^)(UIView *, NSIndexPath *))rc_refresrcooterBlock { 282 | objc_setAssociatedObject(self, kRCRefresrcooterBlockKey, rc_refresrcooterBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); 283 | } 284 | 285 | - (void (^)(UIView *, NSIndexPath *))rc_refresrcooterBlock { 286 | return objc_getAssociatedObject(self, kRCRefresrcooterBlockKey); 287 | } 288 | 289 | - (void)setRc_willDisplayCellBlock:(void (^)(UIView *, NSIndexPath *))rc_willDisplayCellBlock { 290 | objc_setAssociatedObject(self, kRCWillDispalyCellBlockKey, rc_willDisplayCellBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); 291 | } 292 | 293 | - (void (^)(UIView *, NSIndexPath *))rc_willDisplayCellBlock { 294 | return objc_getAssociatedObject(self, kRCWillDispalyCellBlockKey); 295 | } 296 | 297 | - (void)setRc_didEndDisplayingCellBlock:(void (^)(UIView *, NSIndexPath *))rc_didEndDisplayingCellBlock { 298 | objc_setAssociatedObject(self, kRCDidEndDispalyingCellBlockKey, rc_didEndDisplayingCellBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); 299 | } 300 | 301 | - (void (^)(UIView *, NSIndexPath *))rc_didEndDisplayingCellBlock { 302 | return objc_getAssociatedObject(self, kRCDidEndDispalyingCellBlockKey); 303 | } 304 | 305 | #pragma mark - Private 306 | - (NSString *)reuseIdentifierForCellConfig:(id)config { 307 | NSString *identifier; 308 | if (config && [config respondsToSelector:@selector(rc_cellReuseIdentifier)]) { 309 | identifier = config.rc_cellReuseIdentifier; 310 | } 311 | return identifier ?: NSStringFromClass(config.rc_cellClass); 312 | } 313 | 314 | - (NSString *)reuseIdentifierForHeaderFooterConfig:(id)config { 315 | NSString *identifier; 316 | if (config && [config respondsToSelector:@selector(rc_headerFooterReuseIdentifier)]) { 317 | identifier = config.rc_headerFooterReuseIdentifier; 318 | } 319 | return identifier ?: NSStringFromClass(config.rc_headerFooterClass); 320 | } 321 | 322 | @end 323 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Config/RCCellConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCCellConfig.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "RCCellProtocol.h" 12 | #import "RCCellConfigProtocol.h" 13 | #import "RCSection.h" 14 | 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | @interface RCCellConfig : NSObject 19 | 20 | @property (nonatomic, strong, nullable) id model; 21 | 22 | // Cell类类型 23 | @property (nonatomic, strong, nonnull) Class cellClass; 24 | 25 | // Cell缓存 26 | @property (nonatomic, strong, nullable) UICollectionViewCell *cacheCell; 27 | 28 | // 复用Identifier 29 | @property (nonatomic, strong, nullable) NSString *cellReuseIdentifier; 30 | 31 | // CollectionViewCell itemSize 32 | // TableViewCell height 33 | @property (nonatomic, assign) CGSize itemSize; 34 | 35 | // 子配置数据, cell里面又有一个表 36 | @property (nonatomic, copy) NSArray> *subConfigs; 37 | @property (nonatomic, copy) NSArray *subSections; 38 | 39 | @end 40 | 41 | NS_ASSUME_NONNULL_END 42 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Config/RCCellConfig.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCCellConfig.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "RCCellConfig.h" 10 | 11 | @implementation RCCellConfig 12 | 13 | - (Class)rc_cellClass { 14 | return self.cellClass; 15 | } 16 | 17 | - (NSString *)rc_cellReuseIdentifier { 18 | return self.cellReuseIdentifier ?: NSStringFromClass([self.cellClass class]); 19 | } 20 | 21 | - (CGSize)rc_itemSize { 22 | return self.itemSize; 23 | } 24 | 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Config/RCHeaderFooterConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCHeaderFooterConfig.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "RCHeaderFooterProtocol.h" 12 | #import "RCHeaderFooterConfigProtocol.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface RCHeaderFooterConfig : NSObject 17 | 18 | @property (nonatomic, strong, nullable) id model; 19 | 20 | // header/footer 类类型 21 | @property (nonatomic, strong, nonnull) Class headerFooterClass; 22 | 23 | #pragma mark - optional 24 | 25 | // 复用Identifier 26 | @property (nonatomic, strong, nullable) NSString *headerFooterReuseIdentifier; 27 | 28 | // header/footer height 29 | @property (nonatomic, assign) CGFloat height; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Config/RCHeaderFooterConfig.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCHeaderFooterConfig.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "RCHeaderFooterConfig.h" 10 | 11 | @implementation RCHeaderFooterConfig 12 | 13 | - (Class)rc_headerFooterClass { 14 | return self.headerFooterClass; 15 | } 16 | 17 | - (NSString *)rc_headerFooterReuseIdentifier { 18 | return self.headerFooterReuseIdentifier ?: NSStringFromClass([self.headerFooterClass class]); 19 | } 20 | 21 | - (CGFloat)rc_height { 22 | return self.height; 23 | } 24 | @end 25 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Config/RCSection.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCSection.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "RCHeaderFooterConfigProtocol.h" 12 | #import "RCCellConfigProtocol.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface RCSection : NSObject 17 | 18 | @property (nonatomic, copy) NSArray> *configs; 19 | 20 | @property (nonatomic, strong, nullable) id header; 21 | 22 | @property (nonatomic, strong, nullable) id footer; 23 | 24 | @property (nonatomic, assign) UIEdgeInsets sectionInset; 25 | @property (nonatomic, assign) CGFloat minimumLineSpacing; 26 | @property (nonatomic, assign) CGFloat minimumInteritemSpacing; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Config/RCSection.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCSection.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "RCSection.h" 10 | 11 | @implementation RCSection 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Implement/RCCollectionViewImplement.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCCollectionViewImplement.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RCSection.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface RCCollectionViewImplement : NSObject 15 | 16 | @property (nonatomic, weak, nullable) id cellDelegate; 17 | 18 | @property (nonatomic, copy) NSArray *sections; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Implement/RCCollectionViewImplement.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCCollectionViewImplement.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "RCCollectionViewImplement.h" 10 | #import "UIScrollView+Addition.h" 11 | 12 | @implementation RCCollectionViewImplement 13 | 14 | #pragma mark - UICollectionViewDataSource 15 | 16 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 17 | { 18 | return self.sections.count; 19 | } 20 | 21 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 22 | { 23 | return self.sections[section].configs.count; 24 | } 25 | 26 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 27 | { 28 | if (self.sections.count == 0) { 29 | return [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class]) forIndexPath:indexPath]; 30 | } 31 | RCSection *section = self.sections[indexPath.section]; 32 | id config = section.configs[indexPath.item]; 33 | 34 | NSString *reuseIdentifier = [self reuseIdentifierForCellConfig:config]; 35 | 36 | UICollectionViewCell *cell; 37 | if (!cell) { 38 | cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; 39 | } 40 | 41 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 42 | UICollectionViewCell *rc_cell = (UICollectionViewCell *)cell; 43 | if ([rc_cell respondsToSelector:@selector(rc_indexPath)]) { 44 | rc_cell.rc_indexPath = indexPath; 45 | } 46 | if ([rc_cell respondsToSelector:@selector(rc_cellConifg)]) { 47 | rc_cell.rc_cellConifg = config; 48 | } 49 | if ([rc_cell respondsToSelector:@selector(rc_delegate)]) { 50 | rc_cell.rc_delegate = self.cellDelegate; 51 | } 52 | if ([rc_cell respondsToSelector:@selector(rc_setCellConfig:)]) { 53 | [rc_cell rc_setCellConfig:config]; 54 | } 55 | } 56 | 57 | if (collectionView.rc_refreshCellBlock) { 58 | collectionView.rc_refreshCellBlock(cell, indexPath); 59 | } 60 | 61 | return cell; 62 | } 63 | 64 | - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath 65 | { 66 | id config; 67 | if (kind == UICollectionElementKindSectionHeader) { 68 | config = self.sections[indexPath.section].header; 69 | } else if (kind == UICollectionElementKindSectionFooter){ 70 | config = self.sections[indexPath.section].footer; 71 | } 72 | if (!config) return nil; 73 | 74 | NSString *reuseIdentifier = [self reuseIdentifierForHeaderFooterConfig:config]; 75 | 76 | UICollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; 77 | 78 | if ([view conformsToProtocol:@protocol(RCHeaderFooterProtocol)]) { 79 | UIView *rc_view = (UIView *)view; 80 | if ([rc_view respondsToSelector:@selector(rc_section)]) { 81 | rc_view.rc_section = indexPath.section; 82 | } 83 | if ([rc_view respondsToSelector:@selector(rc_headerFooterConifg)]) { 84 | rc_view.rc_headerFooterConifg = config; 85 | } 86 | if ([rc_view respondsToSelector:@selector(rc_delegate)]) { 87 | rc_view.rc_delegate = self.cellDelegate; 88 | } 89 | if ([rc_view respondsToSelector:@selector(rc_setHeaderFooterConfig:)]) { 90 | [rc_view rc_setHeaderFooterConfig:config]; 91 | } 92 | } 93 | 94 | if (kind == UICollectionElementKindSectionHeader) { 95 | if (collectionView.rc_refreshHeaderBlock) { 96 | collectionView.rc_refreshHeaderBlock(view, indexPath); 97 | } 98 | } else if (kind == UICollectionElementKindSectionFooter){ 99 | if (collectionView.rc_refresrcooterBlock) { 100 | collectionView.rc_refresrcooterBlock(view, indexPath); 101 | } 102 | } 103 | 104 | return view; 105 | } 106 | 107 | #pragma mark - UICollectionViewDelegate 108 | 109 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 110 | { 111 | UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; 112 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 113 | UIView *rc_cell = (UIView *)cell; 114 | if ([rc_cell respondsToSelector:@selector(rc_didSelectCellAtIndexPath:)]) { 115 | [rc_cell rc_didSelectCellAtIndexPath:indexPath]; 116 | } 117 | } 118 | if (collectionView.rc_didSelectCellBlock) { 119 | collectionView.rc_didSelectCellBlock(cell, indexPath); 120 | } 121 | } 122 | 123 | - (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath 124 | { 125 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 126 | UIView *rc_cell = (UIView *)cell; 127 | if ([rc_cell respondsToSelector:@selector(rc_willDisplayCellAtIndexPath:)]) { 128 | [rc_cell rc_willDisplayCellAtIndexPath:indexPath]; 129 | } 130 | } 131 | if (collectionView.rc_willDisplayCellBlock) { 132 | collectionView.rc_willDisplayCellBlock(cell, indexPath); 133 | } 134 | } 135 | 136 | - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath 137 | { 138 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 139 | UIView *rc_cell = (UIView *)cell; 140 | if ([rc_cell respondsToSelector:@selector(rc_didEndDisplayingCellAtIndexPath:)]) { 141 | [rc_cell rc_didEndDisplayingCellAtIndexPath:indexPath]; 142 | } 143 | } 144 | } 145 | 146 | - (void)collectionView:(UICollectionView *)collectionView willDisplaySupplementaryView:(UICollectionReusableView *)view forElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath 147 | { 148 | if ([view conformsToProtocol:@protocol(RCHeaderFooterProtocol)]) { 149 | UIView *rc_view = (UIView *)view; 150 | if ([rc_view respondsToSelector:@selector(rc_willDisplayHeaderFooterInSection:)]) { 151 | [rc_view rc_willDisplayHeaderFooterInSection:indexPath.section]; 152 | } 153 | } 154 | } 155 | 156 | - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingSupplementaryView:(UICollectionReusableView *)view forElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath { 157 | if ([view conformsToProtocol:@protocol(RCHeaderFooterProtocol)]) { 158 | UIView *rc_view = (UIView *)view; 159 | if ([rc_view respondsToSelector:@selector(rc_didEndDisplayingHeaderFooterInSection:)]) { 160 | [rc_view rc_didEndDisplayingHeaderFooterInSection:indexPath.section]; 161 | } 162 | } 163 | } 164 | 165 | #pragma mark - UICollectionViewDelegateFlowLayout 166 | 167 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { 168 | if (indexPath.section >= self.sections.count) return CGSizeMake([UIScreen mainScreen].bounds.size.width, 0.1); 169 | RCSection *section = self.sections[indexPath.section]; 170 | 171 | if (indexPath.item >= section.configs.count) return CGSizeMake([UIScreen mainScreen].bounds.size.width, 0.1); 172 | id config = section.configs[indexPath.item]; 173 | 174 | if (config && [config respondsToSelector:@selector(rc_itemSize)]) { 175 | if (!CGSizeEqualToSize(config.rc_itemSize, CGSizeZero) ) { 176 | return config.rc_itemSize; 177 | } 178 | } 179 | if ([config.rc_cellClass respondsToSelector:@selector(rc_sizeForCellWithConfig:atIndexPath:)]) { 180 | return [config.rc_cellClass rc_sizeForCellWithConfig:config atIndexPath:indexPath]; 181 | } 182 | return CGSizeMake([UIScreen mainScreen].bounds.size.width, 0.1); 183 | } 184 | 185 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section { 186 | id config = self.sections[section].header; 187 | if (config && [config respondsToSelector:@selector(rc_height)]) { 188 | if (config.rc_height > 0) { 189 | return CGSizeMake(MAXFLOAT, config.rc_height); 190 | } 191 | } 192 | if ([config.rc_headerFooterClass respondsToSelector:@selector(rc_heightForHeaderFooterWithConfig:inSection:)]) { 193 | return CGSizeMake(MAXFLOAT, [config.rc_headerFooterClass rc_heightForHeaderFooterWithConfig:config inSection:section]); 194 | } 195 | return CGSizeZero; 196 | } 197 | 198 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section { 199 | id config = self.sections[section].footer; 200 | if (config && [config respondsToSelector:@selector(rc_height)]) { 201 | if (config.rc_height > 0) { 202 | return CGSizeMake(MAXFLOAT, config.rc_height); 203 | } 204 | } 205 | if ([config.rc_headerFooterClass respondsToSelector:@selector(rc_heightForHeaderFooterWithConfig:inSection:)]) { 206 | return CGSizeMake(MAXFLOAT, [config.rc_headerFooterClass rc_heightForHeaderFooterWithConfig:config inSection:section]); 207 | } 208 | return CGSizeZero; 209 | } 210 | 211 | - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { 212 | RCSection *rc_section = self.sections[section]; 213 | if ([collectionViewLayout isKindOfClass:[UICollectionViewFlowLayout class]]) { 214 | UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)collectionViewLayout; 215 | if (!UIEdgeInsetsEqualToEdgeInsets(flowLayout.sectionInset, UIEdgeInsetsZero)) { 216 | return flowLayout.sectionInset; 217 | } 218 | } 219 | return rc_section.sectionInset; 220 | } 221 | 222 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section { 223 | RCSection *rc_section = self.sections[section]; 224 | if ([collectionViewLayout isKindOfClass:[UICollectionViewFlowLayout class]]) { 225 | UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)collectionViewLayout; 226 | if (flowLayout.minimumLineSpacing != 0) { 227 | return flowLayout.minimumLineSpacing; 228 | } 229 | } 230 | return rc_section.minimumLineSpacing; 231 | } 232 | 233 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { 234 | RCSection *rc_section = self.sections[section]; 235 | if ([collectionViewLayout isKindOfClass:[UICollectionViewFlowLayout class]]) { 236 | UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)collectionViewLayout; 237 | if (flowLayout.minimumInteritemSpacing != 0) { 238 | return flowLayout.minimumInteritemSpacing; 239 | } 240 | } 241 | return rc_section.minimumInteritemSpacing; 242 | } 243 | 244 | #pragma nark - UIScrollViewDelegate 245 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 246 | if (![scrollView isKindOfClass:[UICollectionView class]]) return; 247 | UICollectionView *collectionView = (UICollectionView *)scrollView; 248 | 249 | for (UICollectionViewCell *cell in collectionView.visibleCells) { 250 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 251 | UICollectionViewCell *rc_cell = (UICollectionViewCell *)cell; 252 | if ([rc_cell respondsToSelector:@selector(rc_scrollViewWillBeginDragging:)]) { 253 | [rc_cell rc_scrollViewWillBeginDragging:scrollView]; 254 | } 255 | } 256 | } 257 | } 258 | 259 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 260 | { 261 | if (![scrollView isKindOfClass:[UICollectionView class]]) return; 262 | UICollectionView *collectionView = (UICollectionView *)scrollView; 263 | 264 | for (UICollectionViewCell *cell in collectionView.visibleCells) { 265 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 266 | UICollectionViewCell *rc_cell = (UICollectionViewCell *)cell; 267 | if ([rc_cell respondsToSelector:@selector(rc_scrollViewDidScroll:)]) { 268 | [rc_cell rc_scrollViewDidScroll:scrollView]; 269 | } 270 | } 271 | } 272 | } 273 | 274 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 275 | { 276 | if (![scrollView isKindOfClass:[UICollectionView class]]) return; 277 | UICollectionView *collectionView = (UICollectionView *)scrollView; 278 | 279 | for (UICollectionViewCell *cell in collectionView.visibleCells) { 280 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 281 | UICollectionViewCell *rc_cell = (UICollectionViewCell *)cell; 282 | if ([rc_cell respondsToSelector:@selector(rc_scrollViewDidEndDragging:willDecelerate:)]) { 283 | [rc_cell rc_scrollViewDidEndDragging:scrollView willDecelerate:decelerate]; 284 | } 285 | } 286 | } 287 | } 288 | 289 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 290 | { 291 | if (![scrollView isKindOfClass:[UICollectionView class]]) return; 292 | UICollectionView *collectionView = (UICollectionView *)scrollView; 293 | 294 | for (UICollectionViewCell *cell in collectionView.visibleCells) { 295 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 296 | UICollectionViewCell *rc_cell = (UICollectionViewCell *)cell; 297 | if ([rc_cell respondsToSelector:@selector(rc_scrollViewDidEndDecelerating:)]) { 298 | [rc_cell rc_scrollViewDidEndDecelerating:scrollView]; 299 | } 300 | } 301 | } 302 | } 303 | 304 | #pragma mark - Private Method 305 | 306 | - (NSString *)reuseIdentifierForCellConfig:(id)config 307 | { 308 | NSString *identifier; 309 | if (config && [config respondsToSelector:@selector(rc_cellReuseIdentifier)]) { 310 | identifier = config.rc_cellReuseIdentifier; 311 | } 312 | return identifier ?: NSStringFromClass(config.rc_cellClass); 313 | } 314 | 315 | - (NSString *)reuseIdentifierForHeaderFooterConfig:(id)config 316 | { 317 | NSString *identifier; 318 | if (config && [config respondsToSelector:@selector(rc_headerFooterReuseIdentifier)]) { 319 | identifier = config.rc_headerFooterReuseIdentifier; 320 | } 321 | return identifier ?: NSStringFromClass(config.rc_headerFooterClass); 322 | } 323 | 324 | 325 | @end 326 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Implement/RCTableViewImplement.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTableViewImplement.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RCSection.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface RCTableViewImplement : NSObject 15 | 16 | @property (nonatomic, weak, nullable) id cellDelegate; 17 | 18 | @property (nonatomic, copy) NSArray *sections; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Implement/RCTableViewImplement.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCTableViewImplement.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "RCTableViewImplement.h" 10 | #import "UIScrollView+Addition.h" 11 | 12 | @interface RCTableViewImplement () 13 | 14 | @end 15 | 16 | @implementation RCTableViewImplement 17 | 18 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 19 | return self.sections.count; 20 | } 21 | 22 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 23 | return self.sections[section].configs.count; 24 | } 25 | 26 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 27 | if (self.sections.count == 0) { 28 | return [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([UITableViewCell class]) forIndexPath:indexPath]; 29 | } 30 | 31 | RCSection *section = self.sections[indexPath.section]; 32 | id config = section.configs[indexPath.row]; 33 | 34 | NSString *reuseIdentifier = [self reuseIdentifierForCellConfig:config]; 35 | 36 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier forIndexPath:indexPath]; 37 | if (!cell) { 38 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; 39 | } 40 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 41 | UIView *rc_cell = (UIView *)cell; 42 | if ([rc_cell respondsToSelector:@selector(rc_indexPath)]) { 43 | rc_cell.rc_indexPath = indexPath; 44 | } 45 | if ([rc_cell respondsToSelector:@selector(rc_cellConifg)]) { 46 | rc_cell.rc_cellConifg = config; 47 | } 48 | if ([rc_cell respondsToSelector:@selector(rc_delegate)]) { 49 | rc_cell.rc_delegate = self.cellDelegate; 50 | } 51 | if ([rc_cell respondsToSelector:@selector(rc_setCellConfig:)]) { 52 | [rc_cell rc_setCellConfig:config]; 53 | } 54 | } 55 | 56 | if (tableView.rc_refreshCellBlock) { 57 | tableView.rc_refreshCellBlock(cell, indexPath); 58 | } 59 | 60 | return cell; 61 | } 62 | 63 | #pragma mark - UITableViewDelegate 64 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 65 | RCSection *section = self.sections[indexPath.section]; 66 | id config = section.configs[indexPath.row]; 67 | if (config && [config respondsToSelector:@selector(rc_itemSize)]) { 68 | if (config.rc_itemSize.height > 0) { 69 | return config.rc_itemSize.height; 70 | } 71 | } 72 | if ([config.rc_cellClass respondsToSelector:@selector(rc_sizeForCellWithConfig:atIndexPath:)]) { 73 | return [config.rc_cellClass rc_sizeForCellWithConfig:config atIndexPath:indexPath].height; 74 | } 75 | return UITableViewAutomaticDimension; 76 | } 77 | 78 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 79 | id headerConfig = self.sections[section].header; 80 | if (headerConfig && [headerConfig respondsToSelector:@selector(rc_height)]) { 81 | if (headerConfig.rc_height > 0) { 82 | return headerConfig.rc_height; 83 | } 84 | } 85 | if ([headerConfig.rc_headerFooterClass respondsToSelector:@selector(rc_heightForHeaderFooterWithConfig:inSection:)]) { 86 | return [headerConfig.rc_headerFooterClass rc_heightForHeaderFooterWithConfig:headerConfig inSection:section]; 87 | } 88 | return tableView.style == UITableViewStylePlain ? 0 : CGFLOAT_MIN; 89 | } 90 | 91 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 92 | id footerConfig = self.sections[section].footer; 93 | if (footerConfig && [footerConfig respondsToSelector:@selector(rc_height)]) { 94 | if (footerConfig.rc_height > 0) { 95 | return footerConfig.rc_height; 96 | } 97 | } 98 | if ([footerConfig.rc_headerFooterClass respondsToSelector:@selector(rc_heightForHeaderFooterWithConfig:inSection:)]) { 99 | return [footerConfig.rc_headerFooterClass rc_heightForHeaderFooterWithConfig:footerConfig inSection:section]; 100 | } 101 | return tableView.style == UITableViewStylePlain ? 0 : CGFLOAT_MIN; 102 | } 103 | 104 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 105 | id headerConfig = self.sections[section].header; 106 | UIView *header = [self viewForHeaderFooterWithTableView:tableView config:headerConfig section:section]; 107 | if (tableView.rc_refreshHeaderBlock) { 108 | tableView.rc_refreshHeaderBlock(header, [NSIndexPath indexPathForRow:0 inSection:section]); 109 | } 110 | return header; 111 | } 112 | 113 | - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { 114 | id footerConfig = self.sections[section].footer; 115 | UIView *footer = [self viewForHeaderFooterWithTableView:tableView config:footerConfig section:section]; 116 | if (tableView.rc_refresrcooterBlock) { 117 | tableView.rc_refresrcooterBlock(footer, [NSIndexPath indexPathForRow:0 inSection:section]); 118 | } 119 | return footer; 120 | } 121 | 122 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 123 | UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 124 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 125 | UIView *rc_cell = (UIView *)cell; 126 | if ([rc_cell respondsToSelector:@selector(rc_didSelectCellAtIndexPath:)]) { 127 | [rc_cell rc_didSelectCellAtIndexPath:indexPath]; 128 | } 129 | } 130 | if (tableView.rc_didSelectCellBlock) { 131 | tableView.rc_didSelectCellBlock(cell, indexPath); 132 | } 133 | } 134 | 135 | - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 136 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 137 | UIView *rc_cell = (UIView *)cell; 138 | if ([rc_cell respondsToSelector:@selector(rc_willDisplayCellAtIndexPath:)]) { 139 | [rc_cell rc_willDisplayCellAtIndexPath:indexPath]; 140 | } 141 | } 142 | if (tableView.rc_willDisplayCellBlock) { 143 | tableView.rc_willDisplayCellBlock(cell, indexPath); 144 | } 145 | } 146 | 147 | - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(nonnull UITableViewCell *)cell forRowAtIndexPath:(nonnull NSIndexPath *)indexPath { 148 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 149 | UIView *rc_cell = (UIView *)cell; 150 | if ([rc_cell respondsToSelector:@selector(rc_didEndDisplayingCellAtIndexPath:)]) { 151 | [rc_cell rc_didEndDisplayingCellAtIndexPath:indexPath]; 152 | } 153 | } 154 | } 155 | 156 | - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section { 157 | if ([view conformsToProtocol:@protocol(RCHeaderFooterProtocol)]) { 158 | UIView *rc_view = (UIView *)view; 159 | if ([rc_view respondsToSelector:@selector(rc_willDisplayHeaderFooterInSection:)]) { 160 | [rc_view rc_willDisplayHeaderFooterInSection:section]; 161 | } 162 | } 163 | } 164 | 165 | - (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section { 166 | if ([view conformsToProtocol:@protocol(RCHeaderFooterProtocol)]) { 167 | UIView *rc_view = (UIView *)view; 168 | if ([rc_view respondsToSelector:@selector(rc_didEndDisplayingHeaderFooterInSection:)]) { 169 | [rc_view rc_didEndDisplayingHeaderFooterInSection:section]; 170 | } 171 | } 172 | } 173 | 174 | - (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section { 175 | if ([view conformsToProtocol:@protocol(RCHeaderFooterProtocol)]) { 176 | UIView *rc_view = (UIView *)view; 177 | if ([rc_view respondsToSelector:@selector(rc_willDisplayHeaderFooterInSection:)]) { 178 | [rc_view rc_willDisplayHeaderFooterInSection:section]; 179 | } 180 | } 181 | } 182 | 183 | - (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section { 184 | if ([view conformsToProtocol:@protocol(RCHeaderFooterProtocol)]) { 185 | UIView *rc_view = (UIView *)view; 186 | if ([rc_view respondsToSelector:@selector(rc_didEndDisplayingHeaderFooterInSection:)]) { 187 | [rc_view rc_didEndDisplayingHeaderFooterInSection:section]; 188 | } 189 | } 190 | } 191 | 192 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 193 | if (![scrollView isKindOfClass:[UITableView class]]) return; 194 | UITableView *tableView = (UITableView *)scrollView; 195 | for (UITableViewCell *cell in tableView.visibleCells) { 196 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 197 | UITableViewCell *rc_cell = (UITableViewCell *)cell; 198 | if ([rc_cell respondsToSelector:@selector(rc_scrollViewWillBeginDragging:)]) { 199 | [rc_cell rc_scrollViewWillBeginDragging:scrollView]; 200 | } 201 | } 202 | } 203 | } 204 | 205 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 206 | if (![scrollView isKindOfClass:[UITableView class]]) return; 207 | UITableView *tableView = (UITableView *)scrollView; 208 | for (UITableViewCell *cell in tableView.visibleCells) { 209 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 210 | UITableViewCell *rc_cell = (UITableViewCell *)cell; 211 | if ([rc_cell respondsToSelector:@selector(rc_scrollViewDidScroll:)]) { 212 | [rc_cell rc_scrollViewDidScroll:scrollView]; 213 | } 214 | } 215 | } 216 | } 217 | 218 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 219 | if (![scrollView isKindOfClass:[UITableView class]]) return; 220 | UITableView *tableView = (UITableView *)scrollView; 221 | for (UITableViewCell *cell in tableView.visibleCells) { 222 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 223 | UITableViewCell *rc_cell = (UITableViewCell *)cell; 224 | if ([rc_cell respondsToSelector:@selector(rc_scrollViewDidEndDragging:willDecelerate:)]) { 225 | [rc_cell rc_scrollViewDidEndDragging:scrollView willDecelerate:decelerate]; 226 | } 227 | } 228 | } 229 | } 230 | 231 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 232 | if (![scrollView isKindOfClass:[UITableView class]]) return; 233 | UITableView *tableView = (UITableView *)scrollView; 234 | for (UITableViewCell *cell in tableView.visibleCells) { 235 | if ([cell conformsToProtocol:@protocol(RCCellProtocol)]) { 236 | UITableViewCell *rc_cell = (UITableViewCell *)cell; 237 | if ([rc_cell respondsToSelector:@selector(scrollViewDidEndDecelerating:)]) { 238 | [rc_cell rc_scrollViewDidEndDecelerating:scrollView]; 239 | } 240 | } 241 | } 242 | } 243 | 244 | #pragma mark - Private 245 | - (NSString *)reuseIdentifierForCellConfig:(id)config{ 246 | NSString *identifier; 247 | if (config && [config respondsToSelector:@selector(rc_cellReuseIdentifier)]) { 248 | identifier = config.rc_cellReuseIdentifier; 249 | } 250 | return identifier ?: NSStringFromClass(config.rc_cellClass); 251 | } 252 | 253 | - (NSString *)reuseIdentifierForHeaderFooterConfig:(id)config { 254 | NSString *identifier; 255 | if (config && [config respondsToSelector:@selector(rc_headerFooterReuseIdentifier)]) { 256 | identifier = config.rc_headerFooterReuseIdentifier; 257 | } 258 | return identifier ?: NSStringFromClass(config.rc_headerFooterClass); 259 | } 260 | 261 | - (UIView *)viewForHeaderFooterWithTableView:(UITableView *)tableView config:(id)config section:(NSInteger)section { 262 | if (!config) return nil; 263 | 264 | NSString *reuseIdentifier = [self reuseIdentifierForHeaderFooterConfig:config]; 265 | UIView *headerFooterView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:reuseIdentifier]; 266 | if ([headerFooterView conformsToProtocol:@protocol(RCHeaderFooterProtocol)]) { 267 | UIView *rc_view = (UIView *)headerFooterView; 268 | if ([rc_view respondsToSelector:@selector(rc_setHeaderFooterConfig:)]) { 269 | if ([rc_view respondsToSelector:@selector(rc_section)]) { 270 | rc_view.rc_section = section; 271 | } 272 | if ([rc_view respondsToSelector:@selector(rc_headerFooterConifg)]) { 273 | rc_view.rc_headerFooterConifg = config; 274 | } 275 | if ([rc_view respondsToSelector:@selector(rc_delegate)]) { 276 | rc_view.rc_delegate = self.cellDelegate; 277 | } 278 | [rc_view rc_setHeaderFooterConfig:config]; 279 | } 280 | } 281 | return headerFooterView; 282 | } 283 | 284 | 285 | @end 286 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Protocol/RCCellConfigProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCCellConfigProtocol.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @protocol RCCellProtocol; 13 | @protocol RCCellConfigProtocol 14 | @required 15 | // cell类类型 16 | - (Class)rc_cellClass; 17 | 18 | @optional 19 | - (NSString *)rc_cellReuseIdentifier; 20 | 21 | // collectionView itemSize 22 | // tableView height 23 | - (CGSize)rc_itemSize; 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Protocol/RCCellProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCCellProtocol.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @protocol RCCellConfigProtocol; 13 | @protocol RCCellProtocol 14 | 15 | @optional; 16 | 17 | @property (nonatomic, strong) NSIndexPath *rc_indexPath; 18 | 19 | @property (nonatomic, strong) id rc_delegate; 20 | 21 | @property (nonatomic, strong) id rc_cellConifg; 22 | 23 | - (void)rc_setCellConfig:(id)cellConfig; 24 | 25 | + (CGSize)rc_sizeForCellWithConfig:(id)cellConfig atIndexPath:(nullable NSIndexPath *)indexPath; 26 | 27 | - (void)rc_didSelectCellAtIndexPath:(NSIndexPath *)indexPath; 28 | 29 | - (void)rc_willDisplayCellAtIndexPath:(NSIndexPath *)indexPath; 30 | 31 | - (void)rc_didEndDisplayingCellAtIndexPath:(NSIndexPath *)indexPath; 32 | 33 | - (void)rc_scrollViewWillBeginDragging:(UIScrollView *)scrollView; 34 | 35 | - (void)rc_scrollViewDidScroll:(UIScrollView *)scrollView; 36 | 37 | - (void)rc_scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate; 38 | 39 | - (void)rc_scrollViewDidEndDecelerating:(UIScrollView *)scrollView; 40 | 41 | 42 | @end 43 | 44 | NS_ASSUME_NONNULL_END 45 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Protocol/RCHeaderFooterConfigProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCHeaderFooterConfigProtocol.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol RCHeaderFooterProtocol; 14 | 15 | @protocol RCHeaderFooterConfigProtocol 16 | 17 | @required 18 | // header/footer类类型 19 | - (Class)rc_headerFooterClass; 20 | 21 | @optional 22 | // 复用Identifier 23 | - (NSString *)rc_headerFooterReuseIdentifier; 24 | 25 | // header/footer 高度 26 | - (CGFloat)rc_height; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Protocol/RCHeaderFooterProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCHeaderFooterProtocol.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @protocol RCHeaderFooterConfigProtocol; 13 | 14 | @protocol RCHeaderFooterProtocol 15 | 16 | @property (nonatomic, assign) NSInteger rc_section; 17 | @property (nonatomic, strong) id rc_delegate; 18 | @property (nonatomic, strong) id rc_headerFooterConifg; 19 | 20 | - (void)rc_setHeaderFooterConfig:(id)headerFooterConfig; 21 | 22 | + (CGFloat)rc_heightForHeaderFooterWithConfig:(id)headerFooterConfig 23 | inSection:(NSInteger)section; 24 | 25 | - (void)rc_willDisplayHeaderFooterInSection:(NSInteger)section; 26 | 27 | - (void)rc_didEndDisplayingHeaderFooterInSection:(NSInteger)section; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Proxy/RCProxy.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCProxy.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface RCProxy : NSProxy 14 | 15 | @property (nonatomic, strong, readonly) NSPointerArray *targets; 16 | 17 | - (instancetype)initProxy; 18 | 19 | - (void)addTarget:(id)target; 20 | 21 | - (void)removeTarget:(id)target; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/ForwadProxy/Proxy/RCProxy.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCProxy.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2019/10/20. 6 | // Copyright © 2019 linitial. All rights reserved. 7 | // 8 | 9 | #import "RCProxy.h" 10 | 11 | @interface RCProxy () 12 | { 13 | dispatch_semaphore_t _lock; 14 | } 15 | 16 | @end 17 | 18 | @implementation RCProxy 19 | 20 | - (void)dealloc { 21 | #ifdef DEBUG 22 | NSLog(@"%s",__PRETTY_FUNCTION__); 23 | #endif 24 | } 25 | 26 | 27 | - (instancetype)initProxy { 28 | _lock = dispatch_semaphore_create(1); 29 | _targets = [NSPointerArray weakObjectsPointerArray]; 30 | return self; 31 | } 32 | 33 | - (void)addTarget:(id)target { 34 | dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); 35 | [_targets addPointer:NULL]; 36 | [_targets compact]; 37 | for (id t in _targets) { 38 | if (t == target) { 39 | dispatch_semaphore_signal(_lock); 40 | return; 41 | } 42 | } 43 | [_targets addPointer:(__bridge void * _Nullable)(target)]; 44 | dispatch_semaphore_signal(_lock); 45 | } 46 | 47 | - (void)removeTarget:(id)target { 48 | dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); 49 | [_targets addPointer:NULL]; 50 | [_targets compact]; 51 | for (NSUInteger i = 0; i < _targets.count; i++) { 52 | if ([_targets pointerAtIndex:i] == (__bridge void * _Nullable)(target)) { 53 | [_targets removePointerAtIndex:i]; 54 | dispatch_semaphore_signal(_lock); 55 | return; 56 | } 57 | } 58 | dispatch_semaphore_signal(_lock); 59 | 60 | } 61 | 62 | #pragma mark - Forward 63 | - (BOOL)respondsToSelector:(SEL)aSelector { 64 | for (id target in _targets) { 65 | if ([target respondsToSelector:aSelector]) { 66 | return YES; 67 | } 68 | } 69 | return NO; 70 | } 71 | 72 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { 73 | NSMethodSignature *signature; 74 | for (id target in _targets) { 75 | signature = [target methodSignatureForSelector:aSelector]; 76 | if (signature) break; 77 | } 78 | return signature; 79 | } 80 | 81 | - (void)forwardInvocation:(NSInvocation *)anInvocation { 82 | for (id target in _targets) { 83 | if ([target respondsToSelector:anInvocation.selector]) { 84 | [anInvocation invokeWithTarget:target]; 85 | } 86 | } 87 | } 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/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 | 54 | UISupportedInterfaceOrientations~ipad 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationPortraitUpsideDown 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/SceneDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.h 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2020/01/20. 6 | // Copyright © 2020 linitial. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SceneDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow * window; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/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 | -------------------------------------------------------------------------------- /ForwardProxy/ForwardProxy/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ForwardProxy 4 | // 5 | // Created by linitial on 2020/01/20. 6 | // Copyright © 2020 linitial. 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ForwardProxy 2 | 利用NSProxy实现多代理消息分发。 3 | demo为将UITableView与CollectionView的数据源与代理消息转发至cell。 4 | 5 | ### 20200818 6 | 增加NSObject多代理分类 7 | --------------------------------------------------------------------------------