├── .DS_Store ├── InfiniteScrollView ├── .DS_Store ├── InfiniteScrollView.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── schubert.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── schubert.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── InfiniteScrollView.xcscheme │ │ └── xcschememanagement.plist ├── InfiniteScrollView │ ├── .DS_Store │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── .DS_Store │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Img │ │ │ ├── .DS_Store │ │ │ ├── img_01.imageset │ │ │ ├── .DS_Store │ │ │ ├── Contents.json │ │ │ └── img_01.jpg │ │ │ ├── img_02.imageset │ │ │ ├── .DS_Store │ │ │ ├── Contents.json │ │ │ └── img_02.jpg │ │ │ ├── img_03.imageset │ │ │ ├── Contents.json │ │ │ └── img_03.jpg │ │ │ ├── img_04.imageset │ │ │ ├── Contents.json │ │ │ └── img_04.jpg │ │ │ └── img_05.imageset │ │ │ ├── .DS_Store │ │ │ ├── Contents.json │ │ │ └── img_05.jpg │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Controller │ │ ├── .DS_Store │ │ ├── STNewsViewController.h │ │ └── STNewsViewController.m │ ├── Info.plist │ ├── MJExtension │ │ ├── MJArgument.h │ │ ├── MJArgument.m │ │ ├── MJConst.h │ │ ├── MJConst.m │ │ ├── MJExtension.h │ │ ├── MJFoundation.h │ │ ├── MJFoundation.m │ │ ├── MJIvar.h │ │ ├── MJIvar.m │ │ ├── MJMember.h │ │ ├── MJMember.m │ │ ├── MJMethod.h │ │ ├── MJMethod.m │ │ ├── MJType.h │ │ ├── MJType.m │ │ ├── MJTypeEncoding.h │ │ ├── MJTypeEncoding.m │ │ ├── NSObject+MJCoding.h │ │ ├── NSObject+MJCoding.m │ │ ├── NSObject+MJKeyValue.h │ │ ├── NSObject+MJKeyValue.m │ │ ├── NSObject+MJMember.h │ │ └── NSObject+MJMember.m │ ├── Model │ │ ├── STNews.h │ │ └── STNews.m │ ├── PrefixHeader.pch │ ├── View │ │ ├── STNewsCell.h │ │ ├── STNewsCell.m │ │ └── STNewsCell.xib │ ├── main.m │ └── newses.plist └── screenshots │ ├── .DS_Store │ └── 1.png └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/.DS_Store -------------------------------------------------------------------------------- /InfiniteScrollView/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/.DS_Store -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 80021BA21E319E6B00BD30BD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BA11E319E6B00BD30BD /* main.m */; }; 11 | 80021BA51E319E6B00BD30BD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BA41E319E6B00BD30BD /* AppDelegate.m */; }; 12 | 80021BAB1E319E6B00BD30BD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 80021BA91E319E6B00BD30BD /* Main.storyboard */; }; 13 | 80021BAD1E319E6B00BD30BD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 80021BAC1E319E6B00BD30BD /* Assets.xcassets */; }; 14 | 80021BB01E319E6B00BD30BD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 80021BAE1E319E6B00BD30BD /* LaunchScreen.storyboard */; }; 15 | 80021BD91E319F0900BD30BD /* STNewsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BB91E319F0900BD30BD /* STNewsViewController.m */; }; 16 | 80021BDA1E319F0900BD30BD /* MJArgument.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BBC1E319F0900BD30BD /* MJArgument.m */; }; 17 | 80021BDB1E319F0900BD30BD /* MJConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BBE1E319F0900BD30BD /* MJConst.m */; }; 18 | 80021BDC1E319F0900BD30BD /* MJFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BC11E319F0900BD30BD /* MJFoundation.m */; }; 19 | 80021BDD1E319F0900BD30BD /* MJIvar.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BC31E319F0900BD30BD /* MJIvar.m */; }; 20 | 80021BDE1E319F0900BD30BD /* MJMember.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BC51E319F0900BD30BD /* MJMember.m */; }; 21 | 80021BDF1E319F0900BD30BD /* MJMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BC71E319F0900BD30BD /* MJMethod.m */; }; 22 | 80021BE01E319F0900BD30BD /* MJType.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BC91E319F0900BD30BD /* MJType.m */; }; 23 | 80021BE11E319F0900BD30BD /* MJTypeEncoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BCB1E319F0900BD30BD /* MJTypeEncoding.m */; }; 24 | 80021BE21E319F0900BD30BD /* NSObject+MJCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BCD1E319F0900BD30BD /* NSObject+MJCoding.m */; }; 25 | 80021BE31E319F0900BD30BD /* NSObject+MJKeyValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BCF1E319F0900BD30BD /* NSObject+MJKeyValue.m */; }; 26 | 80021BE41E319F0900BD30BD /* NSObject+MJMember.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BD11E319F0900BD30BD /* NSObject+MJMember.m */; }; 27 | 80021BE51E319F0900BD30BD /* STNews.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BD41E319F0900BD30BD /* STNews.m */; }; 28 | 80021BE61E319F0900BD30BD /* STNewsCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 80021BD71E319F0900BD30BD /* STNewsCell.m */; }; 29 | 80021BE71E319F0900BD30BD /* STNewsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 80021BD81E319F0900BD30BD /* STNewsCell.xib */; }; 30 | 80021BEA1E31A03000BD30BD /* newses.plist in Resources */ = {isa = PBXBuildFile; fileRef = 80021BE91E31A03000BD30BD /* newses.plist */; }; 31 | /* End PBXBuildFile section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 80021B9D1E319E6B00BD30BD /* InfiniteScrollView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InfiniteScrollView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | 80021BA11E319E6B00BD30BD /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 36 | 80021BA31E319E6B00BD30BD /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 37 | 80021BA41E319E6B00BD30BD /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 38 | 80021BAA1E319E6B00BD30BD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 39 | 80021BAC1E319E6B00BD30BD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 40 | 80021BAF1E319E6B00BD30BD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 41 | 80021BB11E319E6B00BD30BD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 42 | 80021BB81E319F0900BD30BD /* STNewsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STNewsViewController.h; sourceTree = ""; }; 43 | 80021BB91E319F0900BD30BD /* STNewsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STNewsViewController.m; sourceTree = ""; }; 44 | 80021BBB1E319F0900BD30BD /* MJArgument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJArgument.h; sourceTree = ""; }; 45 | 80021BBC1E319F0900BD30BD /* MJArgument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJArgument.m; sourceTree = ""; }; 46 | 80021BBD1E319F0900BD30BD /* MJConst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJConst.h; sourceTree = ""; }; 47 | 80021BBE1E319F0900BD30BD /* MJConst.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJConst.m; sourceTree = ""; }; 48 | 80021BBF1E319F0900BD30BD /* MJExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJExtension.h; sourceTree = ""; }; 49 | 80021BC01E319F0900BD30BD /* MJFoundation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJFoundation.h; sourceTree = ""; }; 50 | 80021BC11E319F0900BD30BD /* MJFoundation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJFoundation.m; sourceTree = ""; }; 51 | 80021BC21E319F0900BD30BD /* MJIvar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJIvar.h; sourceTree = ""; }; 52 | 80021BC31E319F0900BD30BD /* MJIvar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJIvar.m; sourceTree = ""; }; 53 | 80021BC41E319F0900BD30BD /* MJMember.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJMember.h; sourceTree = ""; }; 54 | 80021BC51E319F0900BD30BD /* MJMember.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJMember.m; sourceTree = ""; }; 55 | 80021BC61E319F0900BD30BD /* MJMethod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJMethod.h; sourceTree = ""; }; 56 | 80021BC71E319F0900BD30BD /* MJMethod.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJMethod.m; sourceTree = ""; }; 57 | 80021BC81E319F0900BD30BD /* MJType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJType.h; sourceTree = ""; }; 58 | 80021BC91E319F0900BD30BD /* MJType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJType.m; sourceTree = ""; }; 59 | 80021BCA1E319F0900BD30BD /* MJTypeEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJTypeEncoding.h; sourceTree = ""; }; 60 | 80021BCB1E319F0900BD30BD /* MJTypeEncoding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJTypeEncoding.m; sourceTree = ""; }; 61 | 80021BCC1E319F0900BD30BD /* NSObject+MJCoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MJCoding.h"; sourceTree = ""; }; 62 | 80021BCD1E319F0900BD30BD /* NSObject+MJCoding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MJCoding.m"; sourceTree = ""; }; 63 | 80021BCE1E319F0900BD30BD /* NSObject+MJKeyValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MJKeyValue.h"; sourceTree = ""; }; 64 | 80021BCF1E319F0900BD30BD /* NSObject+MJKeyValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MJKeyValue.m"; sourceTree = ""; }; 65 | 80021BD01E319F0900BD30BD /* NSObject+MJMember.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MJMember.h"; sourceTree = ""; }; 66 | 80021BD11E319F0900BD30BD /* NSObject+MJMember.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MJMember.m"; sourceTree = ""; }; 67 | 80021BD31E319F0900BD30BD /* STNews.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STNews.h; sourceTree = ""; }; 68 | 80021BD41E319F0900BD30BD /* STNews.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STNews.m; sourceTree = ""; }; 69 | 80021BD61E319F0900BD30BD /* STNewsCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STNewsCell.h; sourceTree = ""; }; 70 | 80021BD71E319F0900BD30BD /* STNewsCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STNewsCell.m; sourceTree = ""; }; 71 | 80021BD81E319F0900BD30BD /* STNewsCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = STNewsCell.xib; sourceTree = ""; }; 72 | 80021BE81E319F5F00BD30BD /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; 73 | 80021BE91E31A03000BD30BD /* newses.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = newses.plist; sourceTree = ""; }; 74 | /* End PBXFileReference section */ 75 | 76 | /* Begin PBXFrameworksBuildPhase section */ 77 | 80021B9A1E319E6B00BD30BD /* Frameworks */ = { 78 | isa = PBXFrameworksBuildPhase; 79 | buildActionMask = 2147483647; 80 | files = ( 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXFrameworksBuildPhase section */ 85 | 86 | /* Begin PBXGroup section */ 87 | 80021B941E319E6B00BD30BD = { 88 | isa = PBXGroup; 89 | children = ( 90 | 80021B9F1E319E6B00BD30BD /* InfiniteScrollView */, 91 | 80021B9E1E319E6B00BD30BD /* Products */, 92 | ); 93 | sourceTree = ""; 94 | }; 95 | 80021B9E1E319E6B00BD30BD /* Products */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 80021B9D1E319E6B00BD30BD /* InfiniteScrollView.app */, 99 | ); 100 | name = Products; 101 | sourceTree = ""; 102 | }; 103 | 80021B9F1E319E6B00BD30BD /* InfiniteScrollView */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 80021BB71E319F0900BD30BD /* Controller */, 107 | 80021BBA1E319F0900BD30BD /* MJExtension */, 108 | 80021BD21E319F0900BD30BD /* Model */, 109 | 80021BD51E319F0900BD30BD /* View */, 110 | 80021BA31E319E6B00BD30BD /* AppDelegate.h */, 111 | 80021BA41E319E6B00BD30BD /* AppDelegate.m */, 112 | 80021BA91E319E6B00BD30BD /* Main.storyboard */, 113 | 80021BAC1E319E6B00BD30BD /* Assets.xcassets */, 114 | 80021BAE1E319E6B00BD30BD /* LaunchScreen.storyboard */, 115 | 80021BB11E319E6B00BD30BD /* Info.plist */, 116 | 80021BA01E319E6B00BD30BD /* Supporting Files */, 117 | ); 118 | path = InfiniteScrollView; 119 | sourceTree = ""; 120 | }; 121 | 80021BA01E319E6B00BD30BD /* Supporting Files */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 80021BE91E31A03000BD30BD /* newses.plist */, 125 | 80021BA11E319E6B00BD30BD /* main.m */, 126 | 80021BE81E319F5F00BD30BD /* PrefixHeader.pch */, 127 | ); 128 | name = "Supporting Files"; 129 | sourceTree = ""; 130 | }; 131 | 80021BB71E319F0900BD30BD /* Controller */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 80021BB81E319F0900BD30BD /* STNewsViewController.h */, 135 | 80021BB91E319F0900BD30BD /* STNewsViewController.m */, 136 | ); 137 | path = Controller; 138 | sourceTree = ""; 139 | }; 140 | 80021BBA1E319F0900BD30BD /* MJExtension */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 80021BBB1E319F0900BD30BD /* MJArgument.h */, 144 | 80021BBC1E319F0900BD30BD /* MJArgument.m */, 145 | 80021BBD1E319F0900BD30BD /* MJConst.h */, 146 | 80021BBE1E319F0900BD30BD /* MJConst.m */, 147 | 80021BBF1E319F0900BD30BD /* MJExtension.h */, 148 | 80021BC01E319F0900BD30BD /* MJFoundation.h */, 149 | 80021BC11E319F0900BD30BD /* MJFoundation.m */, 150 | 80021BC21E319F0900BD30BD /* MJIvar.h */, 151 | 80021BC31E319F0900BD30BD /* MJIvar.m */, 152 | 80021BC41E319F0900BD30BD /* MJMember.h */, 153 | 80021BC51E319F0900BD30BD /* MJMember.m */, 154 | 80021BC61E319F0900BD30BD /* MJMethod.h */, 155 | 80021BC71E319F0900BD30BD /* MJMethod.m */, 156 | 80021BC81E319F0900BD30BD /* MJType.h */, 157 | 80021BC91E319F0900BD30BD /* MJType.m */, 158 | 80021BCA1E319F0900BD30BD /* MJTypeEncoding.h */, 159 | 80021BCB1E319F0900BD30BD /* MJTypeEncoding.m */, 160 | 80021BCC1E319F0900BD30BD /* NSObject+MJCoding.h */, 161 | 80021BCD1E319F0900BD30BD /* NSObject+MJCoding.m */, 162 | 80021BCE1E319F0900BD30BD /* NSObject+MJKeyValue.h */, 163 | 80021BCF1E319F0900BD30BD /* NSObject+MJKeyValue.m */, 164 | 80021BD01E319F0900BD30BD /* NSObject+MJMember.h */, 165 | 80021BD11E319F0900BD30BD /* NSObject+MJMember.m */, 166 | ); 167 | path = MJExtension; 168 | sourceTree = ""; 169 | }; 170 | 80021BD21E319F0900BD30BD /* Model */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 80021BD31E319F0900BD30BD /* STNews.h */, 174 | 80021BD41E319F0900BD30BD /* STNews.m */, 175 | ); 176 | path = Model; 177 | sourceTree = ""; 178 | }; 179 | 80021BD51E319F0900BD30BD /* View */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 80021BD61E319F0900BD30BD /* STNewsCell.h */, 183 | 80021BD71E319F0900BD30BD /* STNewsCell.m */, 184 | 80021BD81E319F0900BD30BD /* STNewsCell.xib */, 185 | ); 186 | path = View; 187 | sourceTree = ""; 188 | }; 189 | /* End PBXGroup section */ 190 | 191 | /* Begin PBXNativeTarget section */ 192 | 80021B9C1E319E6B00BD30BD /* InfiniteScrollView */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = 80021BB41E319E6B00BD30BD /* Build configuration list for PBXNativeTarget "InfiniteScrollView" */; 195 | buildPhases = ( 196 | 80021B991E319E6B00BD30BD /* Sources */, 197 | 80021B9A1E319E6B00BD30BD /* Frameworks */, 198 | 80021B9B1E319E6B00BD30BD /* Resources */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | ); 204 | name = InfiniteScrollView; 205 | productName = InfiniteScrollView; 206 | productReference = 80021B9D1E319E6B00BD30BD /* InfiniteScrollView.app */; 207 | productType = "com.apple.product-type.application"; 208 | }; 209 | /* End PBXNativeTarget section */ 210 | 211 | /* Begin PBXProject section */ 212 | 80021B951E319E6B00BD30BD /* Project object */ = { 213 | isa = PBXProject; 214 | attributes = { 215 | LastUpgradeCheck = 0820; 216 | ORGANIZATIONNAME = schubertq; 217 | TargetAttributes = { 218 | 80021B9C1E319E6B00BD30BD = { 219 | CreatedOnToolsVersion = 8.2.1; 220 | ProvisioningStyle = Automatic; 221 | }; 222 | }; 223 | }; 224 | buildConfigurationList = 80021B981E319E6B00BD30BD /* Build configuration list for PBXProject "InfiniteScrollView" */; 225 | compatibilityVersion = "Xcode 3.2"; 226 | developmentRegion = English; 227 | hasScannedForEncodings = 0; 228 | knownRegions = ( 229 | en, 230 | Base, 231 | ); 232 | mainGroup = 80021B941E319E6B00BD30BD; 233 | productRefGroup = 80021B9E1E319E6B00BD30BD /* Products */; 234 | projectDirPath = ""; 235 | projectRoot = ""; 236 | targets = ( 237 | 80021B9C1E319E6B00BD30BD /* InfiniteScrollView */, 238 | ); 239 | }; 240 | /* End PBXProject section */ 241 | 242 | /* Begin PBXResourcesBuildPhase section */ 243 | 80021B9B1E319E6B00BD30BD /* Resources */ = { 244 | isa = PBXResourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | 80021BB01E319E6B00BD30BD /* LaunchScreen.storyboard in Resources */, 248 | 80021BE71E319F0900BD30BD /* STNewsCell.xib in Resources */, 249 | 80021BEA1E31A03000BD30BD /* newses.plist in Resources */, 250 | 80021BAD1E319E6B00BD30BD /* Assets.xcassets in Resources */, 251 | 80021BAB1E319E6B00BD30BD /* Main.storyboard in Resources */, 252 | ); 253 | runOnlyForDeploymentPostprocessing = 0; 254 | }; 255 | /* End PBXResourcesBuildPhase section */ 256 | 257 | /* Begin PBXSourcesBuildPhase section */ 258 | 80021B991E319E6B00BD30BD /* Sources */ = { 259 | isa = PBXSourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | 80021BDC1E319F0900BD30BD /* MJFoundation.m in Sources */, 263 | 80021BDA1E319F0900BD30BD /* MJArgument.m in Sources */, 264 | 80021BDF1E319F0900BD30BD /* MJMethod.m in Sources */, 265 | 80021BA51E319E6B00BD30BD /* AppDelegate.m in Sources */, 266 | 80021BE51E319F0900BD30BD /* STNews.m in Sources */, 267 | 80021BE61E319F0900BD30BD /* STNewsCell.m in Sources */, 268 | 80021BE01E319F0900BD30BD /* MJType.m in Sources */, 269 | 80021BDE1E319F0900BD30BD /* MJMember.m in Sources */, 270 | 80021BE41E319F0900BD30BD /* NSObject+MJMember.m in Sources */, 271 | 80021BE21E319F0900BD30BD /* NSObject+MJCoding.m in Sources */, 272 | 80021BE11E319F0900BD30BD /* MJTypeEncoding.m in Sources */, 273 | 80021BDD1E319F0900BD30BD /* MJIvar.m in Sources */, 274 | 80021BE31E319F0900BD30BD /* NSObject+MJKeyValue.m in Sources */, 275 | 80021BD91E319F0900BD30BD /* STNewsViewController.m in Sources */, 276 | 80021BDB1E319F0900BD30BD /* MJConst.m in Sources */, 277 | 80021BA21E319E6B00BD30BD /* main.m in Sources */, 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | /* End PBXSourcesBuildPhase section */ 282 | 283 | /* Begin PBXVariantGroup section */ 284 | 80021BA91E319E6B00BD30BD /* Main.storyboard */ = { 285 | isa = PBXVariantGroup; 286 | children = ( 287 | 80021BAA1E319E6B00BD30BD /* Base */, 288 | ); 289 | name = Main.storyboard; 290 | sourceTree = ""; 291 | }; 292 | 80021BAE1E319E6B00BD30BD /* LaunchScreen.storyboard */ = { 293 | isa = PBXVariantGroup; 294 | children = ( 295 | 80021BAF1E319E6B00BD30BD /* Base */, 296 | ); 297 | name = LaunchScreen.storyboard; 298 | sourceTree = ""; 299 | }; 300 | /* End PBXVariantGroup section */ 301 | 302 | /* Begin XCBuildConfiguration section */ 303 | 80021BB21E319E6B00BD30BD /* Debug */ = { 304 | isa = XCBuildConfiguration; 305 | buildSettings = { 306 | ALWAYS_SEARCH_USER_PATHS = NO; 307 | CLANG_ANALYZER_NONNULL = YES; 308 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 309 | CLANG_CXX_LIBRARY = "libc++"; 310 | CLANG_ENABLE_MODULES = YES; 311 | CLANG_ENABLE_OBJC_ARC = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_CONSTANT_CONVERSION = YES; 314 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 315 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 316 | CLANG_WARN_EMPTY_BODY = YES; 317 | CLANG_WARN_ENUM_CONVERSION = YES; 318 | CLANG_WARN_INFINITE_RECURSION = YES; 319 | CLANG_WARN_INT_CONVERSION = YES; 320 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 321 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 322 | CLANG_WARN_UNREACHABLE_CODE = YES; 323 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 324 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 325 | COPY_PHASE_STRIP = NO; 326 | DEBUG_INFORMATION_FORMAT = dwarf; 327 | ENABLE_STRICT_OBJC_MSGSEND = YES; 328 | ENABLE_TESTABILITY = YES; 329 | GCC_C_LANGUAGE_STANDARD = gnu99; 330 | GCC_DYNAMIC_NO_PIC = NO; 331 | GCC_NO_COMMON_BLOCKS = YES; 332 | GCC_OPTIMIZATION_LEVEL = 0; 333 | GCC_PREPROCESSOR_DEFINITIONS = ( 334 | "DEBUG=1", 335 | "$(inherited)", 336 | ); 337 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 338 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 339 | GCC_WARN_UNDECLARED_SELECTOR = YES; 340 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 341 | GCC_WARN_UNUSED_FUNCTION = YES; 342 | GCC_WARN_UNUSED_VARIABLE = YES; 343 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 344 | MTL_ENABLE_DEBUG_INFO = YES; 345 | ONLY_ACTIVE_ARCH = YES; 346 | SDKROOT = iphoneos; 347 | }; 348 | name = Debug; 349 | }; 350 | 80021BB31E319E6B00BD30BD /* Release */ = { 351 | isa = XCBuildConfiguration; 352 | buildSettings = { 353 | ALWAYS_SEARCH_USER_PATHS = NO; 354 | CLANG_ANALYZER_NONNULL = YES; 355 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 356 | CLANG_CXX_LIBRARY = "libc++"; 357 | CLANG_ENABLE_MODULES = YES; 358 | CLANG_ENABLE_OBJC_ARC = YES; 359 | CLANG_WARN_BOOL_CONVERSION = YES; 360 | CLANG_WARN_CONSTANT_CONVERSION = YES; 361 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 362 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 363 | CLANG_WARN_EMPTY_BODY = YES; 364 | CLANG_WARN_ENUM_CONVERSION = YES; 365 | CLANG_WARN_INFINITE_RECURSION = YES; 366 | CLANG_WARN_INT_CONVERSION = YES; 367 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 368 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 369 | CLANG_WARN_UNREACHABLE_CODE = YES; 370 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 371 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 372 | COPY_PHASE_STRIP = NO; 373 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 374 | ENABLE_NS_ASSERTIONS = NO; 375 | ENABLE_STRICT_OBJC_MSGSEND = YES; 376 | GCC_C_LANGUAGE_STANDARD = gnu99; 377 | GCC_NO_COMMON_BLOCKS = YES; 378 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 379 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 380 | GCC_WARN_UNDECLARED_SELECTOR = YES; 381 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 382 | GCC_WARN_UNUSED_FUNCTION = YES; 383 | GCC_WARN_UNUSED_VARIABLE = YES; 384 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 385 | MTL_ENABLE_DEBUG_INFO = NO; 386 | SDKROOT = iphoneos; 387 | VALIDATE_PRODUCT = YES; 388 | }; 389 | name = Release; 390 | }; 391 | 80021BB51E319E6B00BD30BD /* Debug */ = { 392 | isa = XCBuildConfiguration; 393 | buildSettings = { 394 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 395 | GCC_PREFIX_HEADER = /Users/schubert/Documents/workspace/iOS/InfiniteScrollView/InfiniteScrollView/InfiniteScrollView/PrefixHeader.pch; 396 | INFOPLIST_FILE = InfiniteScrollView/Info.plist; 397 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 398 | PRODUCT_BUNDLE_IDENTIFIER = com.schubertq.InfiniteScrollView; 399 | PRODUCT_NAME = "$(TARGET_NAME)"; 400 | }; 401 | name = Debug; 402 | }; 403 | 80021BB61E319E6B00BD30BD /* Release */ = { 404 | isa = XCBuildConfiguration; 405 | buildSettings = { 406 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 407 | GCC_PREFIX_HEADER = /Users/schubert/Documents/workspace/iOS/InfiniteScrollView/InfiniteScrollView/InfiniteScrollView/PrefixHeader.pch; 408 | INFOPLIST_FILE = InfiniteScrollView/Info.plist; 409 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 410 | PRODUCT_BUNDLE_IDENTIFIER = com.schubertq.InfiniteScrollView; 411 | PRODUCT_NAME = "$(TARGET_NAME)"; 412 | }; 413 | name = Release; 414 | }; 415 | /* End XCBuildConfiguration section */ 416 | 417 | /* Begin XCConfigurationList section */ 418 | 80021B981E319E6B00BD30BD /* Build configuration list for PBXProject "InfiniteScrollView" */ = { 419 | isa = XCConfigurationList; 420 | buildConfigurations = ( 421 | 80021BB21E319E6B00BD30BD /* Debug */, 422 | 80021BB31E319E6B00BD30BD /* Release */, 423 | ); 424 | defaultConfigurationIsVisible = 0; 425 | defaultConfigurationName = Release; 426 | }; 427 | 80021BB41E319E6B00BD30BD /* Build configuration list for PBXNativeTarget "InfiniteScrollView" */ = { 428 | isa = XCConfigurationList; 429 | buildConfigurations = ( 430 | 80021BB51E319E6B00BD30BD /* Debug */, 431 | 80021BB61E319E6B00BD30BD /* Release */, 432 | ); 433 | defaultConfigurationIsVisible = 0; 434 | defaultConfigurationName = Release; 435 | }; 436 | /* End XCConfigurationList section */ 437 | }; 438 | rootObject = 80021B951E319E6B00BD30BD /* Project object */; 439 | } 440 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView.xcodeproj/project.xcworkspace/xcuserdata/schubert.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView.xcodeproj/project.xcworkspace/xcuserdata/schubert.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView.xcodeproj/xcuserdata/schubert.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView.xcodeproj/xcuserdata/schubert.xcuserdatad/xcschemes/InfiniteScrollView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView.xcodeproj/xcuserdata/schubert.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | InfiniteScrollView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 80021B9C1E319E6B00BD30BD 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/.DS_Store -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // InfiniteScrollView 4 | // 5 | // Created by schubertq on 2016/2/20. 6 | // Copyright © 2016年 schubertq. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // InfiniteScrollView 4 | // 5 | // Created by schubertq on 2016/2/20. 6 | // Copyright © 2016年 schubertq. 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 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Assets.xcassets/.DS_Store -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/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 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/.DS_Store -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_01.imageset/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_01.imageset/.DS_Store -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_01.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "img_01.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "img_01.jpg", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_01.imageset/img_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_01.imageset/img_01.jpg -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_02.imageset/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_02.imageset/.DS_Store -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_02.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "img_02.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "img_02.jpg", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_02.imageset/img_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_02.imageset/img_02.jpg -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_03.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "img_03.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "img_03.jpg", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_03.imageset/img_03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_03.imageset/img_03.jpg -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_04.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "img_04.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "img_04.jpg", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_04.imageset/img_04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_04.imageset/img_04.jpg -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_05.imageset/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_05.imageset/.DS_Store -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_05.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "img_05.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "img_05.jpg", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_05.imageset/img_05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Assets.xcassets/Img/img_05.imageset/img_05.jpg -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/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 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Controller/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/InfiniteScrollView/Controller/.DS_Store -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Controller/STNewsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // STNewsViewController.h 3 | // InfiniteScrollView 4 | // 5 | // Created by schubertq on 2016/2/20. 6 | // Copyright © 2016年 schubertq. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface STNewsViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Controller/STNewsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // STNewsViewController.m 3 | // InfiniteScrollView 4 | // 5 | // Created by schubertq on 2016/2/20. 6 | // Copyright © 2016年 schubertq. All rights reserved. 7 | // 8 | 9 | #import "STNewsViewController.h" 10 | #import "STNewsCell.h" 11 | #import "MJExtension.h" 12 | #import "STNews.h" 13 | 14 | #define STCellIdentifier @"news" 15 | #define STMaxSections 100 16 | 17 | @interface STNewsViewController () 18 | @property (weak, nonatomic) IBOutlet UICollectionView *collectionView; 19 | @property (nonatomic, weak) IBOutlet UIPageControl *pageContol; 20 | @property (nonatomic, strong) NSArray *newses; 21 | @property (nonatomic, strong) NSTimer *timer; 22 | @end 23 | 24 | @implementation STNewsViewController 25 | 26 | - (NSArray *)newses 27 | { 28 | if (_newses == nil) { 29 | self.newses = [STNews objectArrayWithFilename:@"newses.plist"]; 30 | self.pageContol.numberOfPages = self.newses.count; 31 | } 32 | return _newses; 33 | } 34 | 35 | - (void)viewDidLoad 36 | { 37 | [super viewDidLoad]; 38 | 39 | // 注册cell 40 | [self.collectionView registerNib:[UINib nibWithNibName:@"STNewsCell" bundle:nil] forCellWithReuseIdentifier:STCellIdentifier]; 41 | 42 | // // 1.流水布局 43 | // UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 44 | // // 2.每个cell的尺寸 45 | // layout.itemSize = CGSizeMake(STScreenW, 160); 46 | // // 3.设置cell之间的水平间距 47 | // layout.minimumInteritemSpacing = 0; 48 | // // 4.设置cell之间的垂直间距 49 | // layout.minimumLineSpacing = 0; 50 | // // 5.设置四周的内边距 51 | // layout.sectionInset = UIEdgeInsetsMake(OFProductCellMargin, OFProductCellMargin, 0, OFProductCellMargin); 52 | 53 | UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout; 54 | layout.itemSize = CGSizeMake(STScreenW, 160); 55 | self.collectionView.collectionViewLayout = layout; 56 | 57 | // 默认显示最中间的那组 58 | [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:STMaxSections/2] atScrollPosition:UICollectionViewScrollPositionLeft animated:NO]; 59 | 60 | // 添加定时器 61 | [self addTimer]; 62 | } 63 | 64 | /** 65 | * 添加定时器 66 | */ 67 | - (void)addTimer 68 | { 69 | NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextPage) userInfo:nil repeats:YES]; 70 | [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 71 | self.timer = timer; 72 | } 73 | 74 | /** 75 | * 移除定时器 76 | */ 77 | - (void)removeTimer 78 | { 79 | // 停止定时器 80 | [self.timer invalidate]; 81 | self.timer = nil; 82 | } 83 | 84 | - (NSIndexPath *)resetIndexPath 85 | { 86 | // 当前正在展示的位置 87 | NSIndexPath *currentIndexPath = [[self.collectionView indexPathsForVisibleItems] lastObject]; 88 | // 马上显示回最中间那组的数据 89 | NSIndexPath *currentIndexPathReset = [NSIndexPath indexPathForItem:currentIndexPath.item inSection:STMaxSections/2]; 90 | [self.collectionView scrollToItemAtIndexPath:currentIndexPathReset atScrollPosition:UICollectionViewScrollPositionLeft animated:NO]; 91 | return currentIndexPathReset; 92 | } 93 | 94 | /** 95 | * 下一页 96 | */ 97 | - (void)nextPage 98 | { 99 | // 1.马上显示回最中间那组的数据 100 | NSIndexPath *currentIndexPathReset = [self resetIndexPath]; 101 | 102 | // 2.计算出下一个需要展示的位置 103 | NSInteger nextItem = currentIndexPathReset.item + 1; 104 | NSInteger nextSection = currentIndexPathReset.section; 105 | if (nextItem == self.newses.count) { 106 | nextItem = 0; 107 | nextSection++; 108 | } 109 | NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:nextItem inSection:nextSection]; 110 | 111 | // 3.通过动画滚动到下一个位置 112 | [self.collectionView scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES]; 113 | } 114 | 115 | #pragma mark - UICollectionViewDataSource 116 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 117 | { 118 | return self.newses.count; 119 | } 120 | 121 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 122 | { 123 | return STMaxSections; 124 | } 125 | 126 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 127 | { 128 | STNewsCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:STCellIdentifier forIndexPath:indexPath]; 129 | 130 | cell.news = self.newses[indexPath.item]; 131 | 132 | return cell; 133 | } 134 | 135 | #pragma mark - UICollectionViewDelegate 136 | /** 137 | * 当用户即将开始拖拽的时候就调用 138 | */ 139 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView 140 | { 141 | [self removeTimer]; 142 | } 143 | 144 | /** 145 | * 当用户停止拖拽的时候就调用 146 | */ 147 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 148 | { 149 | // NSLog(@"scrollViewDidEndDragging--松开"); 150 | [self addTimer]; 151 | } 152 | 153 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 154 | { 155 | int page = (int)(scrollView.contentOffset.x / scrollView.bounds.size.width + 0.5) % self.newses.count; 156 | self.pageContol.currentPage = page; 157 | } 158 | @end 159 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJArgument.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJArgument.h 3 | // ItcastWeibo 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 包装一个方法参数 8 | 9 | #import 10 | /** 11 | * 包装一个方法参数 12 | */ 13 | @interface MJArgument : NSObject 14 | /** 参数的索引 */ 15 | @property (nonatomic, assign) int index; 16 | /** 参数类型 */ 17 | @property (nonatomic, copy) NSString *type; 18 | @end 19 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJArgument.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJArgument.m 3 | // ItcastWeibo 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "MJArgument.h" 10 | #import "MJExtension.h" 11 | 12 | @implementation MJArgument 13 | MJLogAllIvrs 14 | @end 15 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJConst.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __MJConst__H__ 3 | #define __MJConst__H__ 4 | 5 | #ifdef DEBUG // 调试状态 6 | // 打开LOG功能 7 | #define MJLog(...) NSLog(__VA_ARGS__) 8 | // 打开断言功能 9 | #define MJAssert(condition, desc) NSAssert(condition, @"\n报错文件:%@\n报错行数:第%d行\n报错方法:%s\n错误描述:%@", [NSString stringWithUTF8String:__FILE__], __LINE__, __FUNCTION__, desc) 10 | #define MJAssertParamNotNil(param) MJAssert(param, [[NSString stringWithFormat:@#param] stringByAppendingString:@"参数不能为nil"]) 11 | #else // 发布状态 12 | // 关闭LOG功能 13 | #define MJLog(...) 14 | // 关闭断言功能 15 | #define MJAssert(condition, desc) 16 | #define MJAssertParamNotNil(param) 17 | #endif 18 | 19 | // 颜色 20 | #define MJColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] 21 | 22 | // 随机色 23 | #define MJRandomColor MJColor(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256)) 24 | 25 | #endif -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJConst.m: -------------------------------------------------------------------------------- 1 | #ifndef __MJConst__M__ 2 | #define __MJConst__M__ 3 | 4 | 5 | 6 | 7 | #endif -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJExtension.h 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "MJTypeEncoding.h" 10 | #import "NSObject+MJCoding.h" 11 | #import "NSObject+MJMember.h" 12 | #import "NSObject+MJKeyValue.h" 13 | 14 | #define MJLogAllIvrs \ 15 | - (NSString *)description \ 16 | { \ 17 | return [self keyValues].description; \ 18 | } 19 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJFoundation.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJFoundation.h 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 14/7/16. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MJFoundation : NSObject 12 | + (BOOL)isClassFromFoundation:(Class)c; 13 | @end 14 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJFoundation.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJFoundation.m 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 14/7/16. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "MJFoundation.h" 10 | #import "MJConst.h" 11 | 12 | static NSArray *_foundationClasses; 13 | 14 | @implementation MJFoundation 15 | 16 | + (void)initialize 17 | { 18 | _foundationClasses = @[@"NSArray",@"NSAutoreleasePool",@"NSBundle",@"NSByteOrder",@"NSCalendar",@"NSCharacterSet",@"NSCoder",@"NSData",@"NSDate",@"NSDateFormatter",@"NSDecimal",@"NSDecimalNumber",@"NSDictionary",@"NSEnumerator",@"NSError",@"NSException",@"NSFileHandle",@"NSFileManager",@"NSFormatter",@"NSHashTable",@"NSHTTPCookie",@"NSHTTPCookieStorage",@"NSIndexPath",@"NSIndexSet",@"NSInvocation",@"NSJSONSerialization",@"NSKeyValueCoding",@"NSKeyValueObserving",@"NSKeyedArchiver",@"NSLocale",@"NSLock",@"NSMapTable",@"NSMethodSignature",@"NSNotification",@"NSNotificationQueue",@"NSNull",@"NSNumberFormatter",@"NSObject",@"NSOperation",@"NSOrderedSet",@"NSOrthography",@"NSPathUtilities",@"NSPointerArray",@"NSPointerFunctions",@"NSPort",@"NSProcessInfo",@"NSPropertyList",@"NSProxy",@"NSRange",@"NSRegularExpression",@"NSRunLoop",@"NSScanner",@"NSSet",@"NSSortDescriptor",@"NSStream",@"NSString",@"NSTextCheckingResult",@"NSThread",@"NSTimeZone",@"NSTimer",@"NSURL",@"NSURLAuthenticationChallenge",@"NSURLCache",@"NSURLConnection",@"NSURLCredential",@"NSURLCredentialStorage",@"NSURLError",@"NSURLProtectionSpace",@"NSURLProtocol",@"NSURLRequest",@"NSURLResponse",@"NSUserDefaults",@"NSValue",@"NSValueTransformer",@"NSXMLParser",@"NSZone"]; 19 | } 20 | 21 | + (BOOL)isClassFromFoundation:(Class)c 22 | { 23 | MJAssertParamNotNil(c); 24 | return [_foundationClasses containsObject:NSStringFromClass(c)]; 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJIvar.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJIvar.h 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 包装一个成员变量 8 | 9 | #import "MJMember.h" 10 | @class MJType; 11 | 12 | /** 13 | * 包装一个成员变量 14 | */ 15 | @interface MJIvar : MJMember 16 | /** 成员变量 */ 17 | @property (nonatomic, assign) Ivar ivar; 18 | /** 成员属性名 */ 19 | @property (nonatomic, copy, readonly) NSString *propertyName; 20 | /** 成员变量的值 */ 21 | @property (nonatomic) id value; 22 | /** 成员变量的类型 */ 23 | @property (nonatomic, strong, readonly) MJType *type; 24 | 25 | /** 26 | * 初始化 27 | * 28 | * @param ivar 成员变量 29 | * @param srcObject 哪个对象的成员变量 30 | * 31 | * @return 初始化好的对象 32 | */ 33 | - (instancetype)initWithIvar:(Ivar)ivar srcObject:(id)srcObject; 34 | @end 35 | 36 | /** 37 | * 遍历成员变量用的block 38 | * 39 | * @param ivar 成员变量的包装对象 40 | * @param stop YES代表停止遍历,NO代表继续遍历 41 | */ 42 | typedef void (^MJIvarsBlock)(MJIvar *ivar, BOOL *stop); -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJIvar.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJIvar.m 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "MJIvar.h" 10 | #import "MJTypeEncoding.h" 11 | #import "MJConst.h" 12 | 13 | @implementation MJIvar 14 | /** 15 | * 初始化 16 | * 17 | * @param ivar 成员变量 18 | * @param srcObject 哪个对象的成员变量 19 | * 20 | * @return 初始化好的对象 21 | */ 22 | - (instancetype)initWithIvar:(Ivar)ivar srcObject:(id)srcObject 23 | { 24 | if (self = [super initWithSrcObject:srcObject]) { 25 | self.ivar = ivar; 26 | } 27 | return self; 28 | } 29 | 30 | /** 31 | * 设置成员变量 32 | */ 33 | - (void)setIvar:(Ivar)ivar 34 | { 35 | _ivar = ivar; 36 | 37 | MJAssertParamNotNil(ivar); 38 | 39 | // 1.成员变量名 40 | _name = [NSString stringWithUTF8String:ivar_getName(ivar)]; 41 | 42 | // 2.属性名 43 | if ([_name hasPrefix:@"_"]) { 44 | _propertyName = [_name stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@""]; 45 | } else { 46 | _propertyName = _name; 47 | } 48 | 49 | // 3.成员变量的类型符 50 | NSString *code = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)]; 51 | _type = [[MJType alloc] initWithCode:code]; 52 | } 53 | 54 | /** 55 | * 获得成员变量的值 56 | */ 57 | - (id)value 58 | { 59 | if (_type.KVCDisabled) return [NSNull null]; 60 | return [_srcObject valueForKey:_propertyName]; 61 | } 62 | 63 | /** 64 | * 设置成员变量的值 65 | */ 66 | - (void)setValue:(id)value 67 | { 68 | if (_type.KVCDisabled) return; 69 | [_srcObject setValue:value forKey:_propertyName]; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJMember.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJMember.h 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "MJType.h" 12 | #import "MJArgument.h" 13 | 14 | @interface MJMember : NSObject 15 | { 16 | __weak id _srcObject; 17 | NSString *_name; 18 | } 19 | /** 成员来源于哪个类(可能是父类) */ 20 | @property (nonatomic, assign) Class srcClass; 21 | /** 成员来源类是否是Foundation框架的 */ 22 | @property (nonatomic, readonly, getter = isSrcClassFromFoundation) BOOL srcClassFromFoundation; 23 | 24 | /** 成员来源于哪个对象 */ 25 | @property (nonatomic, weak, readonly) id srcObject; 26 | 27 | /** 成员名 */ 28 | @property (nonatomic, copy, readonly) NSString *name; 29 | 30 | /** 31 | * 初始化 32 | * 33 | * @param srcObject 来源于哪个对象 34 | * 35 | * @return 初始化好的对象 36 | */ 37 | - (instancetype)initWithSrcObject:(id)srcObject; 38 | @end 39 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJMember.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJMember.m 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "MJMember.h" 10 | #import "MJExtension.h" 11 | #import "MJFoundation.h" 12 | #import "MJConst.h" 13 | 14 | @implementation MJMember 15 | 16 | 17 | /** 18 | * 初始化 19 | * 20 | * @param srcObject 来源于哪个对象 21 | * 22 | * @return 初始化好的对象 23 | */ 24 | - (instancetype)initWithSrcObject:(id)srcObject 25 | { 26 | if (self = [super init]) { 27 | _srcObject = srcObject; 28 | } 29 | return self; 30 | } 31 | 32 | - (void)setSrcClass:(Class)srcClass 33 | { 34 | _srcClass = srcClass; 35 | 36 | MJAssertParamNotNil(srcClass); 37 | 38 | _srcClassFromFoundation = [MJFoundation isClassFromFoundation:srcClass]; 39 | } 40 | 41 | MJLogAllIvrs 42 | @end 43 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJMethod.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJMethod.h 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 包装一个方法 8 | 9 | #import "MJMember.h" 10 | /** 11 | * 包装一个方法 12 | */ 13 | @interface MJMethod : MJMember 14 | /** 方法 */ 15 | @property (nonatomic, assign) Method method; 16 | /** 方法名 */ 17 | @property (nonatomic, assign, readonly) SEL selector; 18 | /** 所有的参数(都是MJArgument对象) */ 19 | @property (nonatomic, strong, readonly) NSArray *arguments; 20 | /** 返回值类型 */ 21 | @property (nonatomic, copy, readonly) NSString *returnType; 22 | /** 23 | * 初始化 24 | * 25 | * @param method 方法 26 | * @param srcObject 哪个对象的方法 27 | * 28 | * @return 初始化好的对象 29 | */ 30 | - (instancetype)initWitSTethod:(Method)method srcObject:(id)srcObject; 31 | @end 32 | 33 | /** 34 | * 遍历方法用的block 35 | * 36 | * @param method 方法的包装对象 37 | * @param stop YES代表停止遍历,NO代表继续遍历 38 | */ 39 | typedef void (^MJMethodsBlock)(MJMethod *method, BOOL *stop); 40 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJMethod.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJMethod.m 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "MJMethod.h" 10 | #import "MJConst.h" 11 | 12 | @implementation MJMethod 13 | /** 14 | * 初始化 15 | * 16 | * @param method 方法 17 | * @param srcObject 哪个对象的方法 18 | * 19 | * @return 初始化好的对象 20 | */ 21 | - (instancetype)initWitSTethod:(Method)method srcObject:(id)srcObject 22 | { 23 | if (self = [super initWithSrcObject:srcObject]) { 24 | self.method = method; 25 | } 26 | return self; 27 | } 28 | 29 | /** 30 | * 设置方法 31 | */ 32 | - (void)setMethod:(Method)method 33 | { 34 | _method = method; 35 | 36 | MJAssertParamNotNil(method); 37 | 38 | // 1.方法选择器 39 | _selector = method_getName(method); 40 | _name = NSStringFromSelector(self.selector); 41 | 42 | // 2.参数 43 | int step = 2; // 跳过前面的2个参数 44 | int argsCount = method_getNumberOfArguments(method); 45 | NSMutableArray *args = [NSMutableArray arrayWithCapacity:argsCount - step]; 46 | for (int i = step; i 10 | /** 11 | * 包装一种类型 12 | */ 13 | @interface MJType : NSObject 14 | /** 类型标识符 */ 15 | @property (nonatomic, copy) NSString *code; 16 | 17 | /** 对象类型(如果是基本数据类型,此值为nil) */ 18 | @property (nonatomic, assign, readonly) Class typeClass; 19 | 20 | /** 类型是否来自于Foundation框架,比如NSString、NSArray */ 21 | @property (nonatomic, readonly, getter = isFromFoundation) BOOL fromFoundation; 22 | /** 类型是否不支持KVC */ 23 | @property (nonatomic, readonly, getter = isKVCDisabled) BOOL KVCDisabled; 24 | 25 | /** 26 | * 初始化一个类型对象 27 | * 28 | * @param code 类型标识符 29 | */ 30 | - (instancetype)initWithCode:(NSString *)code; 31 | @end -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJType.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJType.m 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "MJType.h" 10 | #import "MJExtension.h" 11 | #import "MJFoundation.h" 12 | #import "MJConst.h" 13 | 14 | @implementation MJType 15 | 16 | - (instancetype)initWithCode:(NSString *)code 17 | { 18 | if (self = [super init]) { 19 | self.code = code; 20 | } 21 | return self; 22 | } 23 | 24 | /** 类型标识符 */ 25 | - (void)setCode:(NSString *)code 26 | { 27 | _code = code; 28 | 29 | MJAssertParamNotNil(code); 30 | 31 | if (code.length == 0 || [code isEqualToString:MJTypeSEL] || 32 | [code isEqualToString:MJTypeIvar] || 33 | [code isEqualToString:MJTypeMethod]) { 34 | _KVCDisabled = YES; 35 | } else if ([code hasPrefix:@"@"] && code.length > 3) { 36 | // 去掉@"和",截取中间的类型名称 37 | _code = [code substringFromIndex:2]; 38 | _code = [_code substringToIndex:_code.length - 1]; 39 | _typeClass = NSClassFromString(_code); 40 | 41 | _fromFoundation = [MJFoundation isClassFromFoundation:_typeClass]; 42 | } 43 | } 44 | 45 | MJLogAllIvrs 46 | @end 47 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJTypeEncoding.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJTypeEncoding.h 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | /** 9 | * 类型(属性类型) 10 | */ 11 | extern NSString *const MJTypeInt; 12 | extern NSString *const MJTypeFloat; 13 | extern NSString *const MJTypeDouble; 14 | extern NSString *const MJTypeLong; 15 | extern NSString *const MJTypeLongLong; 16 | extern NSString *const MJTypeChar; 17 | extern NSString *const MJTypeBOOL; 18 | extern NSString *const MJTypePointer; 19 | 20 | extern NSString *const MJTypeIvar; 21 | extern NSString *const MJTypeMethod; 22 | extern NSString *const MJTypeBlock; 23 | extern NSString *const MJTypeClass; 24 | extern NSString *const MJTypeSEL; 25 | extern NSString *const MJTypeId; 26 | 27 | /** 28 | * 返回值类型 29 | */ 30 | extern NSString *const MJReturnTypeVoid; 31 | extern NSString *const MJReturnTypeObject; 32 | 33 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/MJTypeEncoding.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJTypeEncoding.m 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | /** 9 | * 成员变量类型(属性类型) 10 | */ 11 | NSString *const MJTypeInt = @"i"; 12 | NSString *const MJTypeFloat = @"f"; 13 | NSString *const MJTypeDouble = @"d"; 14 | NSString *const MJTypeLong = @"q"; 15 | NSString *const MJTypeLongLong = @"q"; 16 | NSString *const MJTypeChar = @"c"; 17 | NSString *const MJTypeBOOL = @"c"; 18 | NSString *const MJTypePointer = @"*"; 19 | 20 | NSString *const MJTypeIvar = @"^{objc_ivar=}"; 21 | NSString *const MJTypeMethod = @"^{objc_method=}"; 22 | NSString *const MJTypeBlock = @"@?"; 23 | NSString *const MJTypeClass = @"#"; 24 | NSString *const MJTypeSEL = @":"; 25 | NSString *const MJTypeId = @"@"; 26 | 27 | /** 28 | * 返回值类型(如果是unsigned,就是大写) 29 | */ 30 | NSString *const MJReturnTypeVoid = @"v"; 31 | NSString *const MJReturnTypeObject = @"@"; 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/NSObject+MJCoding.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJCoding.h 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (MJCoding) 12 | /** 13 | * 解码(从文件中解析对象) 14 | */ 15 | - (void)decode:(NSCoder *)decoder; 16 | /** 17 | * 编码(将对象写入文件中) 18 | */ 19 | - (void)encode:(NSCoder *)encoder; 20 | @end 21 | 22 | /** 23 | 归档的实现 24 | */ 25 | #define MJCodingImplementation \ 26 | - (id)initWithCoder:(NSCoder *)decoder \ 27 | { \ 28 | if (self = [super init]) { \ 29 | [self decode:decoder]; \ 30 | } \ 31 | return self; \ 32 | } \ 33 | \ 34 | - (void)encodeWithCoder:(NSCoder *)encoder \ 35 | { \ 36 | [self encode:encoder]; \ 37 | } -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/NSObject+MJCoding.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJCoding.m 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "NSObject+MJCoding.h" 10 | #import "NSObject+MJMember.h" 11 | 12 | @implementation NSObject (MJCoding) 13 | /** 14 | * 编码(将对象写入文件中) 15 | */ 16 | - (void)encode:(NSCoder *)encoder 17 | { 18 | [self enumerateIvarsWithBlock:^(MJIvar *ivar, BOOL *stop) { 19 | if (ivar.isSrcClassFromFoundation) return; 20 | [encoder encodeObject:ivar.value forKey:ivar.name]; 21 | }]; 22 | } 23 | 24 | /** 25 | * 解码(从文件中解析对象) 26 | */ 27 | - (void)decode:(NSCoder *)decoder 28 | { 29 | [self enumerateIvarsWithBlock:^(MJIvar *ivar, BOOL *stop) { 30 | if (ivar.isSrcClassFromFoundation) return; 31 | ivar.value = [decoder decodeObjectForKey:ivar.name]; 32 | }]; 33 | } 34 | @end 35 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/NSObject+MJKeyValue.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJKeyValue.h 3 | // MJExtension 4 | // 5 | // Created by mj on 13-8-24. 6 | // Copyright (c) 2013年 itcast. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * KeyValue协议 13 | */ 14 | @protocol MJKeyValue 15 | @optional 16 | /** 17 | * 将属性名换为其他key去字典中取值 18 | * 19 | * @return 字典中的key是属性名,value是从字典中取值用的key 20 | */ 21 | - (NSDictionary *)replacedKeyFromPropertyName; 22 | 23 | /** 24 | * 数组中需要转换的模型类 25 | * 26 | * @return 字典中的key是数组属性名,value是数组中存放模型的Class 27 | */ 28 | - (NSDictionary *)objectClassInArray; 29 | 30 | /** 31 | * 当字典转模型完毕时调用 32 | */ 33 | - (void)keyValuesDidFinishConvertingToObject; 34 | 35 | /** 36 | * 当模型转字典完毕时调用 37 | */ 38 | - (void)objectDidFinishConvertingToKeyValues; 39 | @end 40 | 41 | @interface NSObject (MJKeyValue) 42 | /** 43 | * 将字典的键值对转成模型属性 44 | * @param keyValues 字典 45 | */ 46 | - (void)setKeyValues:(NSDictionary *)keyValues; 47 | 48 | /** 49 | * 将模型转成字典 50 | * @return 字典 51 | */ 52 | - (NSDictionary *)keyValues; 53 | 54 | /** 55 | * 通过模型数组来创建一个字典数组 56 | * @param objectArray 模型数组 57 | * @return 字典数组 58 | */ 59 | + (NSArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray; 60 | 61 | #pragma mark - 字典转模型 62 | /** 63 | * 通过JSON数据来创建一个模型 64 | * @param data JSON数据 65 | * @return 新建的对象 66 | */ 67 | + (instancetype)objectWithJSONData:(NSData *)data; 68 | 69 | /** 70 | * 通过字典来创建一个模型 71 | * @param keyValues 字典 72 | * @return 新建的对象 73 | */ 74 | + (instancetype)objectWithKeyValues:(NSDictionary *)keyValues; 75 | 76 | /** 77 | * 通过plist来创建一个模型 78 | * @param filename 文件名(仅限于mainBundle中的文件) 79 | * @return 新建的对象 80 | */ 81 | + (instancetype)objectWithFilename:(NSString *)filename; 82 | 83 | /** 84 | * 通过plist来创建一个模型 85 | * @param file 文件全路径 86 | * @return 新建的对象 87 | */ 88 | + (instancetype)objectWithFile:(NSString *)file; 89 | 90 | #pragma mark - 字典数组转模型数组 91 | /** 92 | * 通过JSON数据来创建一个模型数组 93 | * @param data JSON数据 94 | * @return 新建的对象 95 | */ 96 | + (NSArray *)objectArrayWithJSONData:(NSData *)data; 97 | 98 | /** 99 | * 通过字典数组来创建一个模型数组 100 | * @param keyValuesArray 字典数组 101 | * @return 模型数组 102 | */ 103 | + (NSArray *)objectArrayWithKeyValuesArray:(NSArray *)keyValuesArray; 104 | 105 | /** 106 | * 通过plist来创建一个模型数组 107 | * @param filename 文件名(仅限于mainBundle中的文件) 108 | * @return 模型数组 109 | */ 110 | + (NSArray *)objectArrayWithFilename:(NSString *)filename; 111 | 112 | /** 113 | * 通过plist来创建一个模型数组 114 | * @param file 文件全路径 115 | * @return 模型数组 116 | */ 117 | + (NSArray *)objectArrayWithFile:(NSString *)file; 118 | @end 119 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/NSObject+MJKeyValue.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJKeyValue.m 3 | // MJExtension 4 | // 5 | // Created by mj on 13-8-24. 6 | // Copyright (c) 2013年 itcast. All rights reserved. 7 | // 8 | 9 | #import "NSObject+MJKeyValue.h" 10 | #import "NSObject+MJMember.h" 11 | #import "MJConst.h" 12 | 13 | @implementation NSObject (MJKeyValue) 14 | #pragma mark - 公共方法 15 | #pragma mark - 字典转模型 16 | /** 17 | * 通过JSON数据来创建一个模型 18 | * @param data JSON数据 19 | * @return 新建的对象 20 | */ 21 | + (instancetype)objectWithJSONData:(NSData *)data 22 | { 23 | MJAssertParamNotNil(data); 24 | 25 | NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; 26 | return [self objectWithKeyValues:dict]; 27 | } 28 | 29 | /** 30 | * 通过字典来创建一个模型 31 | * @param keyValues 字典 32 | * @return 新建的对象 33 | */ 34 | + (instancetype)objectWithKeyValues:(NSDictionary *)keyValues 35 | { 36 | NSString *desc = [NSString stringWithFormat:@"keyValues is not a NSDictionary - keyValues参数不是一个字典, keyValues is a %@ - keyValues参数是一个%@", keyValues.class, keyValues.class]; 37 | MJAssert([keyValues isKindOfClass:[NSDictionary class]], desc); 38 | 39 | id model = [[self alloc] init]; 40 | [model setKeyValues:keyValues]; 41 | return model; 42 | } 43 | 44 | /** 45 | * 通过plist来创建一个模型 46 | * @param filename 文件名(仅限于mainBundle中的文件) 47 | * @return 新建的对象 48 | */ 49 | + (instancetype)objectWithFilename:(NSString *)filename 50 | { 51 | MJAssertParamNotNil(filename); 52 | NSString *file = [[NSBundle mainBundle] pathForResource:filename ofType:nil]; 53 | return [self objectWithFile:file]; 54 | } 55 | 56 | /** 57 | * 通过plist来创建一个模型 58 | * @param file 文件全路径 59 | * @return 新建的对象 60 | */ 61 | + (instancetype)objectWithFile:(NSString *)file 62 | { 63 | MJAssertParamNotNil(file); 64 | NSDictionary *keyValues = [NSDictionary dictionaryWithContentsOfFile:file]; 65 | return [self objectWithKeyValues:keyValues]; 66 | } 67 | 68 | /** 69 | * 将字典的键值对转成模型属性 70 | * @param keyValues 字典 71 | */ 72 | - (void)setKeyValues:(NSDictionary *)keyValues 73 | { 74 | NSString *desc = [NSString stringWithFormat:@"keyValues is not a NSDictionary - keyValues参数不是一个字典, keyValues is a %@ - keyValues参数是一个%@", keyValues.class, keyValues.class]; 75 | MJAssert([keyValues isKindOfClass:[NSDictionary class]], desc); 76 | 77 | [self enumerateIvarsWithBlock:^(MJIvar *ivar, BOOL *stop) { 78 | // 来自Foundation框架的成员变量,直接返回 79 | if (ivar.isSrcClassFromFoundation) return; 80 | 81 | // 1.取出属性值 82 | NSString *key = [self keyWithPropertyName:ivar.propertyName]; 83 | id value = keyValues[key]; 84 | if (!value || [value isKindOfClass:[NSNull class]]) return; 85 | 86 | // 2.如果是模型属性 87 | if (ivar.type.typeClass && !ivar.type.isFromFoundation) { 88 | value = [ivar.type.typeClass objectWithKeyValues:value]; 89 | } else if ([self respondsToSelector:@selector(objectClassInArray)]) { 90 | // 3.字典数组-->模型数组 91 | Class objectClass = self.objectClassInArray[ivar.propertyName]; 92 | if (objectClass) { 93 | value = [objectClass objectArrayWithKeyValuesArray:value]; 94 | } 95 | } 96 | 97 | // 4.赋值 98 | ivar.value = value; 99 | }]; 100 | 101 | // 转换完毕 102 | if ([self respondsToSelector:@selector(keyValuesDidFinishConvertingToObject)]) { 103 | [self keyValuesDidFinishConvertingToObject]; 104 | } 105 | } 106 | 107 | /** 108 | * 将模型转成字典 109 | * @return 字典 110 | */ 111 | - (NSDictionary *)keyValues 112 | { 113 | NSMutableDictionary *keyValues = [NSMutableDictionary dictionary]; 114 | 115 | [self enumerateIvarsWithBlock:^(MJIvar *ivar, BOOL *stop) { 116 | if (ivar.isSrcClassFromFoundation) return; 117 | 118 | // 1.取出属性值 119 | id value = ivar.value; 120 | if (!value) return; 121 | 122 | // 2.如果是模型属性 123 | if (ivar.type.typeClass && !ivar.type.isFromFoundation) { 124 | value = [value keyValues]; 125 | } else if ([self respondsToSelector:@selector(objectClassInArray)]) { 126 | // 3.处理数组里面有模型的情况 127 | Class objectClass = self.objectClassInArray[ivar.propertyName]; 128 | if (objectClass) { 129 | value = [objectClass keyValuesArrayWithObjectArray:value]; 130 | } 131 | } 132 | 133 | // 4.赋值 134 | NSString *key = [self keyWithPropertyName:ivar.propertyName]; 135 | keyValues[key] = value; 136 | }]; 137 | 138 | // 转换完毕 139 | if ([self respondsToSelector:@selector(objectDidFinishConvertingToKeyValues)]) { 140 | [self objectDidFinishConvertingToKeyValues]; 141 | } 142 | 143 | return keyValues; 144 | } 145 | 146 | /** 147 | * 通过JSON数据来创建一个模型数组 148 | * @param data JSON数据 149 | * @return 新建的对象 150 | */ 151 | + (NSArray *)objectArrayWithJSONData:(NSData *)data 152 | { 153 | MJAssertParamNotNil(data); 154 | 155 | NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; 156 | return [self objectArrayWithKeyValuesArray:array]; 157 | } 158 | 159 | /** 160 | * 通过模型数组来创建一个字典数组 161 | * @param objectArray 模型数组 162 | * @return 字典数组 163 | */ 164 | + (NSArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray 165 | { 166 | // 0.判断真实性 167 | NSString *desc = [NSString stringWithFormat:@"objectArray is not a NSArray - objectArray不是一个数组, objectArray is a %@ - objectArray参数是一个%@", objectArray.class, objectArray.class]; 168 | MJAssert([objectArray isKindOfClass:[NSArray class]], desc); 169 | 170 | // 1.过滤 171 | if (![objectArray isKindOfClass:[NSArray class]]) return objectArray; 172 | if (![[objectArray lastObject] isKindOfClass:self]) return objectArray; 173 | 174 | // 2.创建数组 175 | NSMutableArray *keyValuesArray = [NSMutableArray array]; 176 | for (id object in objectArray) { 177 | [keyValuesArray addObject:[object keyValues]]; 178 | } 179 | return keyValuesArray; 180 | } 181 | 182 | #pragma mark - 字典数组转模型数组 183 | /** 184 | * 通过字典数组来创建一个模型数组 185 | * @param keyValuesArray 字典数组 186 | * @return 模型数组 187 | */ 188 | + (NSArray *)objectArrayWithKeyValuesArray:(NSArray *)keyValuesArray 189 | { 190 | // 1.判断真实性 191 | NSString *desc = [NSString stringWithFormat:@"keyValuesArray is not a keyValuesArray - keyValuesArray不是一个数组, keyValuesArray is a %@ - keyValuesArray参数是一个%@", keyValuesArray.class, keyValuesArray.class]; 192 | MJAssert([keyValuesArray isKindOfClass:[NSArray class]], desc); 193 | 194 | // 2.创建数组 195 | NSMutableArray *modelArray = [NSMutableArray array]; 196 | 197 | // 3.遍历 198 | for (NSDictionary *keyValues in keyValuesArray) { 199 | if (![keyValues isKindOfClass:[NSDictionary class]]) continue; 200 | 201 | id model = [self objectWithKeyValues:keyValues]; 202 | [modelArray addObject:model]; 203 | } 204 | 205 | return modelArray; 206 | } 207 | 208 | /** 209 | * 通过plist来创建一个模型数组 210 | * @param filename 文件名(仅限于mainBundle中的文件) 211 | * @return 模型数组 212 | */ 213 | + (NSArray *)objectArrayWithFilename:(NSString *)filename 214 | { 215 | MJAssertParamNotNil(filename); 216 | NSString *file = [[NSBundle mainBundle] pathForResource:filename ofType:nil]; 217 | return [self objectArrayWithFile:file]; 218 | } 219 | 220 | /** 221 | * 通过plist来创建一个模型数组 222 | * @param file 文件全路径 223 | * @return 模型数组 224 | */ 225 | + (NSArray *)objectArrayWithFile:(NSString *)file 226 | { 227 | MJAssertParamNotNil(file); 228 | NSArray *keyValuesArray = [NSArray arrayWithContentsOfFile:file]; 229 | return [self objectArrayWithKeyValuesArray:keyValuesArray]; 230 | } 231 | 232 | #pragma mark - 私有方法 233 | /** 234 | * 根据属性名获得对应的key 235 | * 236 | * @param propertyName 属性名 237 | * 238 | * @return 字典的key 239 | */ 240 | - (NSString *)keyWithPropertyName:(NSString *)propertyName 241 | { 242 | MJAssertParamNotNil(propertyName); 243 | NSString *key = nil; 244 | // 1.查看有没有需要替换的key 245 | if ([self respondsToSelector:@selector(replacedKeyFromPropertyName)]) { 246 | key = self.replacedKeyFromPropertyName[propertyName]; 247 | } 248 | // 2.用属性名作为key 249 | if (!key) key = propertyName; 250 | 251 | return key; 252 | } 253 | @end 254 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/NSObject+MJMember.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJMember.h 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MJIvar.h" 11 | #import "MJMethod.h" 12 | 13 | /** 14 | * 遍历所有类的block(父类) 15 | */ 16 | typedef void (^MJClassesBlock)(Class c, BOOL *stop); 17 | 18 | @interface NSObject (MJMember) 19 | 20 | /** 21 | * 遍历所有的成员变量 22 | */ 23 | - (void)enumerateIvarsWithBlock:(MJIvarsBlock)block; 24 | 25 | /** 26 | * 遍历所有的方法 27 | */ 28 | - (void)enumerateMethodsWithBlock:(MJMethodsBlock)block; 29 | 30 | /** 31 | * 遍历所有的类 32 | */ 33 | - (void)enumerateClassesWithBlock:(MJClassesBlock)block; 34 | @end 35 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/MJExtension/NSObject+MJMember.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJMember.m 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 itcast. All rights reserved. 7 | // 8 | 9 | #import "NSObject+MJMember.h" 10 | 11 | 12 | @implementation NSObject (MJMember) 13 | 14 | /** 15 | * 遍历所有的成员变量 16 | */ 17 | - (void)enumerateIvarsWithBlock:(MJIvarsBlock)block 18 | { 19 | [self enumerateClassesWithBlock:^(__unsafe_unretained Class c, BOOL *stop) { 20 | // 1.获得所有的成员变量 21 | unsigned int outCount = 0; 22 | Ivar *ivars = class_copyIvarList(c, &outCount); 23 | 24 | // 2.遍历每一个成员变量 25 | for (int i = 0; i 9 | 10 | @interface STNews : NSObject 11 | @property (copy, nonatomic) NSString *title; 12 | @property (copy, nonatomic) NSString *icon; 13 | @end 14 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/Model/STNews.m: -------------------------------------------------------------------------------- 1 | // 2 | // STNews.m 3 | // InfiniteScrollView 4 | // 5 | // Created by schubertq on 2016/2/20. 6 | // Copyright © 2016年 schubertq. All rights reserved. 7 | // 8 | 9 | #import "STNews.h" 10 | 11 | @implementation STNews 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // InfiniteScrollView 4 | // 5 | // Created by schubert on 2016/2/20. 6 | // Copyright © 2016年 schubertq. All rights reserved. 7 | // 8 | 9 | #ifndef PrefixHeader_pch 10 | #define PrefixHeader_pch 11 | 12 | // Include any system framework and library headers here that should be included in all compilation units. 13 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 14 | #ifdef __OBJC__ 15 | #import 16 | #import 17 | 18 | // 颜色 19 | #define STColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] 20 | #define STColorRGBA(r, g, b, a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:a] 21 | 22 | // 随机色 23 | #define STRandomColor STColor(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256)) 24 | 25 | // 生成一个字符串 26 | #define NSString(...) [NSString stringWithFormat:__VA_ARGS__] 27 | // 屏幕尺寸 28 | #define STScreenW [UIScreen mainScreen].bounds.size.width 29 | #define STScreenH [UIScreen mainScreen].bounds.size.height 30 | 31 | #endif 32 | #endif /* PrefixHeader_pch */ 33 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/View/STNewsCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // STNewsCell.h 3 | // InfiniteScrollView 4 | // 5 | // Created by schubertq on 2016/2/20. 6 | // Copyright © 2016年 schubertq. All rights reserved. 7 | // 8 | 9 | #import 10 | @class STNews; 11 | @interface STNewsCell : UICollectionViewCell 12 | @property (nonatomic, strong) STNews *news; 13 | @end 14 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/View/STNewsCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // STNewsCell.m 3 | // InfiniteScrollView 4 | // 5 | // Created by schubertq on 2016/2/20. 6 | // Copyright © 2016年 schubertq. All rights reserved. 7 | // 8 | 9 | #import "STNewsCell.h" 10 | #import "STNews.h" 11 | 12 | @interface STNewsCell() 13 | @property (weak, nonatomic) IBOutlet UILabel *titleLabel; 14 | @property (weak, nonatomic) IBOutlet UIImageView *iconView; 15 | @end 16 | 17 | @implementation STNewsCell 18 | - (void)setNews:(STNews *)news 19 | { 20 | _news = news; 21 | 22 | self.iconView.image = [UIImage imageNamed:news.icon]; 23 | self.titleLabel.text = NSString(@" %@", news.title); 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/View/STNewsCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // InfiniteScrollView 4 | // 5 | // Created by schubert on 2016/2/20. 6 | // Copyright © 2016年 schubertq. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /InfiniteScrollView/InfiniteScrollView/newses.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | icon 7 | img_01 8 | title 9 | 九寨沟1 10 | 11 | 12 | icon 13 | img_02 14 | title 15 | 九寨沟2 16 | 17 | 18 | icon 19 | img_03 20 | title 21 | 九寨沟3 22 | 23 | 24 | icon 25 | img_04 26 | title 27 | 九寨沟4 28 | 29 | 30 | icon 31 | img_05 32 | title 33 | 九寨沟5 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /InfiniteScrollView/screenshots/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/screenshots/.DS_Store -------------------------------------------------------------------------------- /InfiniteScrollView/screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schubertq/InfiniteScrollView/3c4da154b20e9273b4f3141db217479922da9c81/InfiniteScrollView/screenshots/1.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # InfiniteScrollView 2 | 利用UICollectionView实现的无限滚动控件 3 | === 4 | 5 | 6 | --------------------------------------------------------------------------------