├── .gitignore ├── LICENSE ├── MSParallaxDemo.gif ├── MSParallaxDemo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── MSParallaxDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon-1024@2x.png │ │ ├── icon-20-ipad.png │ │ ├── icon-20@2x-ipad.png │ │ ├── icon-20@2x.png │ │ ├── icon-20@3x.png │ │ ├── icon-29-ipad.png │ │ ├── icon-29.png │ │ ├── icon-29@2x-ipad.png │ │ ├── icon-29@2x.png │ │ ├── icon-29@3x.png │ │ ├── icon-40.png │ │ ├── icon-40@2x.png │ │ ├── icon-40@3x.png │ │ ├── icon-50.png │ │ ├── icon-50@2x.png │ │ ├── icon-57.png │ │ ├── icon-57@2x.png │ │ ├── icon-60@2x.png │ │ ├── icon-60@3x.png │ │ ├── icon-72.png │ │ ├── icon-72@2x.png │ │ ├── icon-76.png │ │ ├── icon-76@2x.png │ │ └── icon-83.5@2x.png │ ├── Contents.json │ ├── LaunchImage.launchimage │ │ ├── 1024iPadPortraitWOSBiOS56_768x1004pt.png │ │ ├── 1024iPadPortraitWOSBiOS56_768x1004pt@2x.png │ │ ├── 1024iPadPortraitiOS56_768x1024pt.png │ │ ├── 1024iPadPortraitiOS56_768x1024pt@2x.png │ │ ├── 1024iPadPortraitiOS789_768x1024pt.png │ │ ├── 1024iPadPortraitiOS789_768x1024pt@2x.png │ │ ├── 1024iPhonePortraitiOS56_320x480pt.png │ │ ├── 1024iPhonePortraitiOS56_320x480pt@2x.png │ │ ├── 1024iPhonePortraitiOS56_320x568pt@2x.png │ │ ├── 1024iPhonePortraitiOS789_320x480pt@2x.png │ │ ├── 1024iPhonePortraitiOS789_320x568pt@2x.png │ │ ├── 1024iPhonePortraitiOS89_375x667pt@2x.png │ │ ├── 1024iPhonePortraitiOS89_414x736pt@3x.png │ │ └── Contents.json │ ├── parallax_back.imageset │ │ ├── Contents.json │ │ └── parallax_back@3x.png │ ├── parallax_front.imageset │ │ ├── Contents.json │ │ └── parallax_front@3x.png │ └── parallax_middle.imageset │ │ ├── Contents.json │ │ └── parallax_middle@3x.png ├── Info.plist ├── MSParallaxViewController.h ├── MSParallaxViewController.m ├── animationView │ ├── MSParallaxAnimationCell.h │ ├── MSParallaxAnimationCell.m │ ├── MSParallaxCollectionViewBack.h │ ├── MSParallaxCollectionViewBack.m │ ├── MSParallaxCollectionViewFront.h │ ├── MSParallaxCollectionViewFront.m │ ├── MSParallaxCollectionViewMiddle.h │ ├── MSParallaxCollectionViewMiddle.m │ ├── MSParallaxHorizonFlowLayout.h │ └── MSParallaxHorizonFlowLayout.m └── main.m └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | # CocoaPods 34 | # 35 | # We recommend against adding the Pods directory to your .gitignore. However 36 | # you should judge for yourself, the pros and cons are mentioned at: 37 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 38 | # 39 | # Pods/ 40 | # 41 | # Add this line if you want to avoid checking in source code from the Xcode workspace 42 | # *.xcworkspace 43 | 44 | # Carthage 45 | # 46 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 47 | # Carthage/Checkouts 48 | 49 | Carthage/Build/ 50 | 51 | # fastlane 52 | # 53 | # It is recommended to not store the screenshots in the git repo. 54 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 55 | # For more information about the recommended setup visit: 56 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 57 | 58 | fastlane/report.xml 59 | fastlane/Preview.html 60 | fastlane/screenshots/**/*.png 61 | fastlane/test_output 62 | 63 | # Code Injection 64 | # 65 | # After new code Injection tools there's a generated folder /iOSInjectionProject 66 | # https://github.com/johnno1962/injectionforxcode 67 | 68 | iOSInjectionProject/ 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 sureJiang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MSParallaxDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo.gif -------------------------------------------------------------------------------- /MSParallaxDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0E31667324814A2B00AEEAA2 /* MSParallaxHorizonFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E31667124814A2B00AEEAA2 /* MSParallaxHorizonFlowLayout.m */; }; 11 | 0E31667C248151E900AEEAA2 /* MSParallaxCollectionViewBack.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E31667B248151E900AEEAA2 /* MSParallaxCollectionViewBack.m */; }; 12 | 0EC40F5C2481168700372ECC /* MSParallaxAnimationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EC40F5B2481168700372ECC /* MSParallaxAnimationCell.m */; }; 13 | 0EC40F5F24811D0400372ECC /* MSParallaxCollectionViewMiddle.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EC40F5E24811D0400372ECC /* MSParallaxCollectionViewMiddle.m */; }; 14 | 0EC40F6224811D1700372ECC /* MSParallaxCollectionViewFront.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EC40F6124811D1700372ECC /* MSParallaxCollectionViewFront.m */; }; 15 | FF01804E2480EC1B00BE9117 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FF01804D2480EC1B00BE9117 /* AppDelegate.m */; }; 16 | FF0180592480EC1C00BE9117 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FF0180582480EC1C00BE9117 /* Assets.xcassets */; }; 17 | FF01805F2480EC1C00BE9117 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FF01805E2480EC1C00BE9117 /* main.m */; }; 18 | FF0180832480EC9700BE9117 /* MSParallaxViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FF0180822480EC9700BE9117 /* MSParallaxViewController.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | FF0180652480EC1C00BE9117 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = FF0180412480EC1B00BE9117 /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = FF0180482480EC1B00BE9117; 27 | remoteInfo = Test_Demo; 28 | }; 29 | FF0180702480EC1C00BE9117 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = FF0180412480EC1B00BE9117 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = FF0180482480EC1B00BE9117; 34 | remoteInfo = Test_Demo; 35 | }; 36 | /* End PBXContainerItemProxy section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 0E31667124814A2B00AEEAA2 /* MSParallaxHorizonFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSParallaxHorizonFlowLayout.m; sourceTree = ""; }; 40 | 0E31667224814A2B00AEEAA2 /* MSParallaxHorizonFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSParallaxHorizonFlowLayout.h; sourceTree = ""; }; 41 | 0E31667A248151E900AEEAA2 /* MSParallaxCollectionViewBack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSParallaxCollectionViewBack.h; sourceTree = ""; }; 42 | 0E31667B248151E900AEEAA2 /* MSParallaxCollectionViewBack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSParallaxCollectionViewBack.m; sourceTree = ""; }; 43 | 0EC40F5A2481168700372ECC /* MSParallaxAnimationCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSParallaxAnimationCell.h; sourceTree = ""; }; 44 | 0EC40F5B2481168700372ECC /* MSParallaxAnimationCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSParallaxAnimationCell.m; sourceTree = ""; }; 45 | 0EC40F5D24811D0400372ECC /* MSParallaxCollectionViewMiddle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSParallaxCollectionViewMiddle.h; sourceTree = ""; }; 46 | 0EC40F5E24811D0400372ECC /* MSParallaxCollectionViewMiddle.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSParallaxCollectionViewMiddle.m; sourceTree = ""; }; 47 | 0EC40F6024811D1700372ECC /* MSParallaxCollectionViewFront.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSParallaxCollectionViewFront.h; sourceTree = ""; }; 48 | 0EC40F6124811D1700372ECC /* MSParallaxCollectionViewFront.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSParallaxCollectionViewFront.m; sourceTree = ""; }; 49 | FF0180492480EC1B00BE9117 /* MSParallaxDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MSParallaxDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | FF01804C2480EC1B00BE9117 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 51 | FF01804D2480EC1B00BE9117 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 52 | FF0180582480EC1C00BE9117 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 53 | FF01805D2480EC1C00BE9117 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | FF01805E2480EC1C00BE9117 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 55 | FF0180642480EC1C00BE9117 /* MSParallaxDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MSParallaxDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | FF01806F2480EC1C00BE9117 /* MSParallaxDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MSParallaxDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | FF0180812480EC9700BE9117 /* MSParallaxViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSParallaxViewController.h; sourceTree = ""; }; 58 | FF0180822480EC9700BE9117 /* MSParallaxViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSParallaxViewController.m; sourceTree = ""; }; 59 | /* End PBXFileReference section */ 60 | 61 | /* Begin PBXFrameworksBuildPhase section */ 62 | FF0180462480EC1B00BE9117 /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | FF0180612480EC1C00BE9117 /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | FF01806C2480EC1C00BE9117 /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | /* End PBXFrameworksBuildPhase section */ 84 | 85 | /* Begin PBXGroup section */ 86 | 0EC40F632481234000372ECC /* animationView */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 0EC40F5A2481168700372ECC /* MSParallaxAnimationCell.h */, 90 | 0EC40F5B2481168700372ECC /* MSParallaxAnimationCell.m */, 91 | 0E31667A248151E900AEEAA2 /* MSParallaxCollectionViewBack.h */, 92 | 0E31667B248151E900AEEAA2 /* MSParallaxCollectionViewBack.m */, 93 | 0EC40F5D24811D0400372ECC /* MSParallaxCollectionViewMiddle.h */, 94 | 0EC40F5E24811D0400372ECC /* MSParallaxCollectionViewMiddle.m */, 95 | 0EC40F6024811D1700372ECC /* MSParallaxCollectionViewFront.h */, 96 | 0EC40F6124811D1700372ECC /* MSParallaxCollectionViewFront.m */, 97 | 0E31667224814A2B00AEEAA2 /* MSParallaxHorizonFlowLayout.h */, 98 | 0E31667124814A2B00AEEAA2 /* MSParallaxHorizonFlowLayout.m */, 99 | ); 100 | path = animationView; 101 | sourceTree = ""; 102 | }; 103 | FF0180402480EC1B00BE9117 = { 104 | isa = PBXGroup; 105 | children = ( 106 | FF01804B2480EC1B00BE9117 /* MSParallaxDemo */, 107 | FF01804A2480EC1B00BE9117 /* Products */, 108 | ); 109 | sourceTree = ""; 110 | }; 111 | FF01804A2480EC1B00BE9117 /* Products */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | FF0180492480EC1B00BE9117 /* MSParallaxDemo.app */, 115 | FF0180642480EC1C00BE9117 /* MSParallaxDemoTests.xctest */, 116 | FF01806F2480EC1C00BE9117 /* MSParallaxDemoUITests.xctest */, 117 | ); 118 | name = Products; 119 | sourceTree = ""; 120 | }; 121 | FF01804B2480EC1B00BE9117 /* MSParallaxDemo */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | FF01804C2480EC1B00BE9117 /* AppDelegate.h */, 125 | FF01804D2480EC1B00BE9117 /* AppDelegate.m */, 126 | FF0180812480EC9700BE9117 /* MSParallaxViewController.h */, 127 | FF0180822480EC9700BE9117 /* MSParallaxViewController.m */, 128 | 0EC40F632481234000372ECC /* animationView */, 129 | FF0180582480EC1C00BE9117 /* Assets.xcassets */, 130 | FF01805D2480EC1C00BE9117 /* Info.plist */, 131 | FF01805E2480EC1C00BE9117 /* main.m */, 132 | ); 133 | path = MSParallaxDemo; 134 | sourceTree = ""; 135 | }; 136 | /* End PBXGroup section */ 137 | 138 | /* Begin PBXNativeTarget section */ 139 | FF0180482480EC1B00BE9117 /* MSParallaxDemo */ = { 140 | isa = PBXNativeTarget; 141 | buildConfigurationList = FF0180782480EC1C00BE9117 /* Build configuration list for PBXNativeTarget "MSParallaxDemo" */; 142 | buildPhases = ( 143 | FF0180452480EC1B00BE9117 /* Sources */, 144 | FF0180462480EC1B00BE9117 /* Frameworks */, 145 | FF0180472480EC1B00BE9117 /* Resources */, 146 | ); 147 | buildRules = ( 148 | ); 149 | dependencies = ( 150 | ); 151 | name = MSParallaxDemo; 152 | productName = Test_Demo; 153 | productReference = FF0180492480EC1B00BE9117 /* MSParallaxDemo.app */; 154 | productType = "com.apple.product-type.application"; 155 | }; 156 | FF0180632480EC1C00BE9117 /* MSParallaxDemoTests */ = { 157 | isa = PBXNativeTarget; 158 | buildConfigurationList = FF01807B2480EC1C00BE9117 /* Build configuration list for PBXNativeTarget "MSParallaxDemoTests" */; 159 | buildPhases = ( 160 | FF0180602480EC1C00BE9117 /* Sources */, 161 | FF0180612480EC1C00BE9117 /* Frameworks */, 162 | FF0180622480EC1C00BE9117 /* Resources */, 163 | ); 164 | buildRules = ( 165 | ); 166 | dependencies = ( 167 | FF0180662480EC1C00BE9117 /* PBXTargetDependency */, 168 | ); 169 | name = MSParallaxDemoTests; 170 | productName = Test_DemoTests; 171 | productReference = FF0180642480EC1C00BE9117 /* MSParallaxDemoTests.xctest */; 172 | productType = "com.apple.product-type.bundle.unit-test"; 173 | }; 174 | FF01806E2480EC1C00BE9117 /* MSParallaxDemoUITests */ = { 175 | isa = PBXNativeTarget; 176 | buildConfigurationList = FF01807E2480EC1C00BE9117 /* Build configuration list for PBXNativeTarget "MSParallaxDemoUITests" */; 177 | buildPhases = ( 178 | FF01806B2480EC1C00BE9117 /* Sources */, 179 | FF01806C2480EC1C00BE9117 /* Frameworks */, 180 | FF01806D2480EC1C00BE9117 /* Resources */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | FF0180712480EC1C00BE9117 /* PBXTargetDependency */, 186 | ); 187 | name = MSParallaxDemoUITests; 188 | productName = Test_DemoUITests; 189 | productReference = FF01806F2480EC1C00BE9117 /* MSParallaxDemoUITests.xctest */; 190 | productType = "com.apple.product-type.bundle.ui-testing"; 191 | }; 192 | /* End PBXNativeTarget section */ 193 | 194 | /* Begin PBXProject section */ 195 | FF0180412480EC1B00BE9117 /* Project object */ = { 196 | isa = PBXProject; 197 | attributes = { 198 | LastUpgradeCheck = 1120; 199 | ORGANIZATIONNAME = "曹笑竹"; 200 | TargetAttributes = { 201 | FF0180482480EC1B00BE9117 = { 202 | CreatedOnToolsVersion = 11.2.1; 203 | }; 204 | FF0180632480EC1C00BE9117 = { 205 | CreatedOnToolsVersion = 11.2.1; 206 | TestTargetID = FF0180482480EC1B00BE9117; 207 | }; 208 | FF01806E2480EC1C00BE9117 = { 209 | CreatedOnToolsVersion = 11.2.1; 210 | TestTargetID = FF0180482480EC1B00BE9117; 211 | }; 212 | }; 213 | }; 214 | buildConfigurationList = FF0180442480EC1B00BE9117 /* Build configuration list for PBXProject "MSParallaxDemo" */; 215 | compatibilityVersion = "Xcode 9.3"; 216 | developmentRegion = en; 217 | hasScannedForEncodings = 0; 218 | knownRegions = ( 219 | en, 220 | Base, 221 | ); 222 | mainGroup = FF0180402480EC1B00BE9117; 223 | productRefGroup = FF01804A2480EC1B00BE9117 /* Products */; 224 | projectDirPath = ""; 225 | projectRoot = ""; 226 | targets = ( 227 | FF0180482480EC1B00BE9117 /* MSParallaxDemo */, 228 | FF0180632480EC1C00BE9117 /* MSParallaxDemoTests */, 229 | FF01806E2480EC1C00BE9117 /* MSParallaxDemoUITests */, 230 | ); 231 | }; 232 | /* End PBXProject section */ 233 | 234 | /* Begin PBXResourcesBuildPhase section */ 235 | FF0180472480EC1B00BE9117 /* Resources */ = { 236 | isa = PBXResourcesBuildPhase; 237 | buildActionMask = 2147483647; 238 | files = ( 239 | FF0180592480EC1C00BE9117 /* Assets.xcassets in Resources */, 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | }; 243 | FF0180622480EC1C00BE9117 /* Resources */ = { 244 | isa = PBXResourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | }; 250 | FF01806D2480EC1C00BE9117 /* Resources */ = { 251 | isa = PBXResourcesBuildPhase; 252 | buildActionMask = 2147483647; 253 | files = ( 254 | ); 255 | runOnlyForDeploymentPostprocessing = 0; 256 | }; 257 | /* End PBXResourcesBuildPhase section */ 258 | 259 | /* Begin PBXSourcesBuildPhase section */ 260 | FF0180452480EC1B00BE9117 /* Sources */ = { 261 | isa = PBXSourcesBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | 0E31667324814A2B00AEEAA2 /* MSParallaxHorizonFlowLayout.m in Sources */, 265 | 0E31667C248151E900AEEAA2 /* MSParallaxCollectionViewBack.m in Sources */, 266 | FF01804E2480EC1B00BE9117 /* AppDelegate.m in Sources */, 267 | 0EC40F5C2481168700372ECC /* MSParallaxAnimationCell.m in Sources */, 268 | 0EC40F6224811D1700372ECC /* MSParallaxCollectionViewFront.m in Sources */, 269 | FF01805F2480EC1C00BE9117 /* main.m in Sources */, 270 | FF0180832480EC9700BE9117 /* MSParallaxViewController.m in Sources */, 271 | 0EC40F5F24811D0400372ECC /* MSParallaxCollectionViewMiddle.m in Sources */, 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | FF0180602480EC1C00BE9117 /* Sources */ = { 276 | isa = PBXSourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | }; 282 | FF01806B2480EC1C00BE9117 /* Sources */ = { 283 | isa = PBXSourcesBuildPhase; 284 | buildActionMask = 2147483647; 285 | files = ( 286 | ); 287 | runOnlyForDeploymentPostprocessing = 0; 288 | }; 289 | /* End PBXSourcesBuildPhase section */ 290 | 291 | /* Begin PBXTargetDependency section */ 292 | FF0180662480EC1C00BE9117 /* PBXTargetDependency */ = { 293 | isa = PBXTargetDependency; 294 | target = FF0180482480EC1B00BE9117 /* MSParallaxDemo */; 295 | targetProxy = FF0180652480EC1C00BE9117 /* PBXContainerItemProxy */; 296 | }; 297 | FF0180712480EC1C00BE9117 /* PBXTargetDependency */ = { 298 | isa = PBXTargetDependency; 299 | target = FF0180482480EC1B00BE9117 /* MSParallaxDemo */; 300 | targetProxy = FF0180702480EC1C00BE9117 /* PBXContainerItemProxy */; 301 | }; 302 | /* End PBXTargetDependency section */ 303 | 304 | /* Begin XCBuildConfiguration section */ 305 | FF0180762480EC1C00BE9117 /* Debug */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ALWAYS_SEARCH_USER_PATHS = NO; 309 | CLANG_ANALYZER_NONNULL = YES; 310 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 311 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 312 | CLANG_CXX_LIBRARY = "libc++"; 313 | CLANG_ENABLE_MODULES = YES; 314 | CLANG_ENABLE_OBJC_ARC = YES; 315 | CLANG_ENABLE_OBJC_WEAK = YES; 316 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 317 | CLANG_WARN_BOOL_CONVERSION = YES; 318 | CLANG_WARN_COMMA = YES; 319 | CLANG_WARN_CONSTANT_CONVERSION = YES; 320 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 321 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 322 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 323 | CLANG_WARN_EMPTY_BODY = YES; 324 | CLANG_WARN_ENUM_CONVERSION = YES; 325 | CLANG_WARN_INFINITE_RECURSION = YES; 326 | CLANG_WARN_INT_CONVERSION = YES; 327 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 328 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 329 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 330 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 331 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 332 | CLANG_WARN_STRICT_PROTOTYPES = YES; 333 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 334 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 335 | CLANG_WARN_UNREACHABLE_CODE = YES; 336 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 337 | COPY_PHASE_STRIP = NO; 338 | DEBUG_INFORMATION_FORMAT = dwarf; 339 | ENABLE_STRICT_OBJC_MSGSEND = YES; 340 | ENABLE_TESTABILITY = YES; 341 | GCC_C_LANGUAGE_STANDARD = gnu11; 342 | GCC_DYNAMIC_NO_PIC = NO; 343 | GCC_NO_COMMON_BLOCKS = YES; 344 | GCC_OPTIMIZATION_LEVEL = 0; 345 | GCC_PREPROCESSOR_DEFINITIONS = ( 346 | "DEBUG=1", 347 | "$(inherited)", 348 | ); 349 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 350 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 351 | GCC_WARN_UNDECLARED_SELECTOR = YES; 352 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 353 | GCC_WARN_UNUSED_FUNCTION = YES; 354 | GCC_WARN_UNUSED_VARIABLE = YES; 355 | IPHONEOS_DEPLOYMENT_TARGET = 13.2; 356 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 357 | MTL_FAST_MATH = YES; 358 | ONLY_ACTIVE_ARCH = YES; 359 | SDKROOT = iphoneos; 360 | }; 361 | name = Debug; 362 | }; 363 | FF0180772480EC1C00BE9117 /* Release */ = { 364 | isa = XCBuildConfiguration; 365 | buildSettings = { 366 | ALWAYS_SEARCH_USER_PATHS = NO; 367 | CLANG_ANALYZER_NONNULL = YES; 368 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 369 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 370 | CLANG_CXX_LIBRARY = "libc++"; 371 | CLANG_ENABLE_MODULES = YES; 372 | CLANG_ENABLE_OBJC_ARC = YES; 373 | CLANG_ENABLE_OBJC_WEAK = YES; 374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 375 | CLANG_WARN_BOOL_CONVERSION = YES; 376 | CLANG_WARN_COMMA = YES; 377 | CLANG_WARN_CONSTANT_CONVERSION = YES; 378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 380 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 381 | CLANG_WARN_EMPTY_BODY = YES; 382 | CLANG_WARN_ENUM_CONVERSION = YES; 383 | CLANG_WARN_INFINITE_RECURSION = YES; 384 | CLANG_WARN_INT_CONVERSION = YES; 385 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 386 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 387 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 388 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 389 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 390 | CLANG_WARN_STRICT_PROTOTYPES = YES; 391 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 392 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 393 | CLANG_WARN_UNREACHABLE_CODE = YES; 394 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 395 | COPY_PHASE_STRIP = NO; 396 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 397 | ENABLE_NS_ASSERTIONS = NO; 398 | ENABLE_STRICT_OBJC_MSGSEND = YES; 399 | GCC_C_LANGUAGE_STANDARD = gnu11; 400 | GCC_NO_COMMON_BLOCKS = YES; 401 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 402 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 403 | GCC_WARN_UNDECLARED_SELECTOR = YES; 404 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 405 | GCC_WARN_UNUSED_FUNCTION = YES; 406 | GCC_WARN_UNUSED_VARIABLE = YES; 407 | IPHONEOS_DEPLOYMENT_TARGET = 13.2; 408 | MTL_ENABLE_DEBUG_INFO = NO; 409 | MTL_FAST_MATH = YES; 410 | SDKROOT = iphoneos; 411 | VALIDATE_PRODUCT = YES; 412 | }; 413 | name = Release; 414 | }; 415 | FF0180792480EC1C00BE9117 /* Debug */ = { 416 | isa = XCBuildConfiguration; 417 | buildSettings = { 418 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 419 | CODE_SIGN_STYLE = Automatic; 420 | DEVELOPMENT_TEAM = 6BF5CN26RG; 421 | GCC_PREFIX_HEADER = ""; 422 | INFOPLIST_FILE = MSParallaxDemo/Info.plist; 423 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 424 | LD_RUNPATH_SEARCH_PATHS = ( 425 | "$(inherited)", 426 | "@executable_path/Frameworks", 427 | ); 428 | PRODUCT_BUNDLE_IDENTIFIER = ByondSoft.MSParallaxDemo; 429 | PRODUCT_NAME = "$(TARGET_NAME)"; 430 | TARGETED_DEVICE_FAMILY = 1; 431 | }; 432 | name = Debug; 433 | }; 434 | FF01807A2480EC1C00BE9117 /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 438 | CODE_SIGN_STYLE = Automatic; 439 | DEVELOPMENT_TEAM = 6BF5CN26RG; 440 | GCC_PREFIX_HEADER = ""; 441 | INFOPLIST_FILE = MSParallaxDemo/Info.plist; 442 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 443 | LD_RUNPATH_SEARCH_PATHS = ( 444 | "$(inherited)", 445 | "@executable_path/Frameworks", 446 | ); 447 | PRODUCT_BUNDLE_IDENTIFIER = ByondSoft.MSParallaxDemo; 448 | PRODUCT_NAME = "$(TARGET_NAME)"; 449 | TARGETED_DEVICE_FAMILY = 1; 450 | }; 451 | name = Release; 452 | }; 453 | FF01807C2480EC1C00BE9117 /* Debug */ = { 454 | isa = XCBuildConfiguration; 455 | buildSettings = { 456 | BUNDLE_LOADER = "$(TEST_HOST)"; 457 | CODE_SIGN_STYLE = Automatic; 458 | DEVELOPMENT_TEAM = 6BF5CN26RG; 459 | INFOPLIST_FILE = Test_DemoTests/Info.plist; 460 | IPHONEOS_DEPLOYMENT_TARGET = 13.2; 461 | LD_RUNPATH_SEARCH_PATHS = ( 462 | "$(inherited)", 463 | "@executable_path/Frameworks", 464 | "@loader_path/Frameworks", 465 | ); 466 | PRODUCT_BUNDLE_IDENTIFIER = "ByondSoft.Test-DemoTests"; 467 | PRODUCT_NAME = "$(TARGET_NAME)"; 468 | TARGETED_DEVICE_FAMILY = "1,2"; 469 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MSParallaxDemo.app/MSParallaxDemo"; 470 | }; 471 | name = Debug; 472 | }; 473 | FF01807D2480EC1C00BE9117 /* Release */ = { 474 | isa = XCBuildConfiguration; 475 | buildSettings = { 476 | BUNDLE_LOADER = "$(TEST_HOST)"; 477 | CODE_SIGN_STYLE = Automatic; 478 | DEVELOPMENT_TEAM = 6BF5CN26RG; 479 | INFOPLIST_FILE = Test_DemoTests/Info.plist; 480 | IPHONEOS_DEPLOYMENT_TARGET = 13.2; 481 | LD_RUNPATH_SEARCH_PATHS = ( 482 | "$(inherited)", 483 | "@executable_path/Frameworks", 484 | "@loader_path/Frameworks", 485 | ); 486 | PRODUCT_BUNDLE_IDENTIFIER = "ByondSoft.Test-DemoTests"; 487 | PRODUCT_NAME = "$(TARGET_NAME)"; 488 | TARGETED_DEVICE_FAMILY = "1,2"; 489 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MSParallaxDemo.app/MSParallaxDemo"; 490 | }; 491 | name = Release; 492 | }; 493 | FF01807F2480EC1C00BE9117 /* Debug */ = { 494 | isa = XCBuildConfiguration; 495 | buildSettings = { 496 | CODE_SIGN_STYLE = Automatic; 497 | DEVELOPMENT_TEAM = 6BF5CN26RG; 498 | INFOPLIST_FILE = Test_DemoUITests/Info.plist; 499 | LD_RUNPATH_SEARCH_PATHS = ( 500 | "$(inherited)", 501 | "@executable_path/Frameworks", 502 | "@loader_path/Frameworks", 503 | ); 504 | PRODUCT_BUNDLE_IDENTIFIER = "ByondSoft.Test-DemoUITests"; 505 | PRODUCT_NAME = "$(TARGET_NAME)"; 506 | TARGETED_DEVICE_FAMILY = "1,2"; 507 | TEST_TARGET_NAME = Test_Demo; 508 | }; 509 | name = Debug; 510 | }; 511 | FF0180802480EC1C00BE9117 /* Release */ = { 512 | isa = XCBuildConfiguration; 513 | buildSettings = { 514 | CODE_SIGN_STYLE = Automatic; 515 | DEVELOPMENT_TEAM = 6BF5CN26RG; 516 | INFOPLIST_FILE = Test_DemoUITests/Info.plist; 517 | LD_RUNPATH_SEARCH_PATHS = ( 518 | "$(inherited)", 519 | "@executable_path/Frameworks", 520 | "@loader_path/Frameworks", 521 | ); 522 | PRODUCT_BUNDLE_IDENTIFIER = "ByondSoft.Test-DemoUITests"; 523 | PRODUCT_NAME = "$(TARGET_NAME)"; 524 | TARGETED_DEVICE_FAMILY = "1,2"; 525 | TEST_TARGET_NAME = Test_Demo; 526 | }; 527 | name = Release; 528 | }; 529 | /* End XCBuildConfiguration section */ 530 | 531 | /* Begin XCConfigurationList section */ 532 | FF0180442480EC1B00BE9117 /* Build configuration list for PBXProject "MSParallaxDemo" */ = { 533 | isa = XCConfigurationList; 534 | buildConfigurations = ( 535 | FF0180762480EC1C00BE9117 /* Debug */, 536 | FF0180772480EC1C00BE9117 /* Release */, 537 | ); 538 | defaultConfigurationIsVisible = 0; 539 | defaultConfigurationName = Release; 540 | }; 541 | FF0180782480EC1C00BE9117 /* Build configuration list for PBXNativeTarget "MSParallaxDemo" */ = { 542 | isa = XCConfigurationList; 543 | buildConfigurations = ( 544 | FF0180792480EC1C00BE9117 /* Debug */, 545 | FF01807A2480EC1C00BE9117 /* Release */, 546 | ); 547 | defaultConfigurationIsVisible = 0; 548 | defaultConfigurationName = Release; 549 | }; 550 | FF01807B2480EC1C00BE9117 /* Build configuration list for PBXNativeTarget "MSParallaxDemoTests" */ = { 551 | isa = XCConfigurationList; 552 | buildConfigurations = ( 553 | FF01807C2480EC1C00BE9117 /* Debug */, 554 | FF01807D2480EC1C00BE9117 /* Release */, 555 | ); 556 | defaultConfigurationIsVisible = 0; 557 | defaultConfigurationName = Release; 558 | }; 559 | FF01807E2480EC1C00BE9117 /* Build configuration list for PBXNativeTarget "MSParallaxDemoUITests" */ = { 560 | isa = XCConfigurationList; 561 | buildConfigurations = ( 562 | FF01807F2480EC1C00BE9117 /* Debug */, 563 | FF0180802480EC1C00BE9117 /* Release */, 564 | ); 565 | defaultConfigurationIsVisible = 0; 566 | defaultConfigurationName = Release; 567 | }; 568 | /* End XCConfigurationList section */ 569 | }; 570 | rootObject = FF0180412480EC1B00BE9117 /* Project object */; 571 | } 572 | -------------------------------------------------------------------------------- /MSParallaxDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MSParallaxDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MSParallaxDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // 4 | // 5 | // Created by JZJ on 2019/5/29. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property(nonatomic,strong) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /MSParallaxDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // 4 | // 5 | // Created by JZJ on 2019/5/29. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "MSParallaxViewController.h" 11 | 12 | 13 | @interface AppDelegate () 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 21 | 22 | self.window = [[UIWindow alloc]init]; 23 | self.window.rootViewController = [MSParallaxViewController new]; 24 | self.window.frame = [UIScreen mainScreen].bounds; 25 | self.window.backgroundColor = UIColor.whiteColor; 26 | [self.window makeKeyAndVisible]; 27 | 28 | 29 | return YES; 30 | } 31 | 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "icon-20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "icon-20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon-29.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "icon-29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "icon-29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "icon-40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "icon-40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "57x57", 47 | "idiom" : "iphone", 48 | "filename" : "icon-57.png", 49 | "scale" : "1x" 50 | }, 51 | { 52 | "size" : "57x57", 53 | "idiom" : "iphone", 54 | "filename" : "icon-57@2x.png", 55 | "scale" : "2x" 56 | }, 57 | { 58 | "size" : "60x60", 59 | "idiom" : "iphone", 60 | "filename" : "icon-60@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "60x60", 65 | "idiom" : "iphone", 66 | "filename" : "icon-60@3x.png", 67 | "scale" : "3x" 68 | }, 69 | { 70 | "size" : "20x20", 71 | "idiom" : "ipad", 72 | "filename" : "icon-20-ipad.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "20x20", 77 | "idiom" : "ipad", 78 | "filename" : "icon-20@2x-ipad.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "29x29", 83 | "idiom" : "ipad", 84 | "filename" : "icon-29-ipad.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "29x29", 89 | "idiom" : "ipad", 90 | "filename" : "icon-29@2x-ipad.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "40x40", 95 | "idiom" : "ipad", 96 | "filename" : "icon-40.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "40x40", 101 | "idiom" : "ipad", 102 | "filename" : "icon-40@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "50x50", 107 | "idiom" : "ipad", 108 | "filename" : "icon-50.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "50x50", 113 | "idiom" : "ipad", 114 | "filename" : "icon-50@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "72x72", 119 | "idiom" : "ipad", 120 | "filename" : "icon-72.png", 121 | "scale" : "1x" 122 | }, 123 | { 124 | "size" : "72x72", 125 | "idiom" : "ipad", 126 | "filename" : "icon-72@2x.png", 127 | "scale" : "2x" 128 | }, 129 | { 130 | "size" : "76x76", 131 | "idiom" : "ipad", 132 | "filename" : "icon-76.png", 133 | "scale" : "1x" 134 | }, 135 | { 136 | "size" : "76x76", 137 | "idiom" : "ipad", 138 | "filename" : "icon-76@2x.png", 139 | "scale" : "2x" 140 | }, 141 | { 142 | "size" : "83.5x83.5", 143 | "idiom" : "ipad", 144 | "filename" : "icon-83.5@2x.png", 145 | "scale" : "2x" 146 | }, 147 | { 148 | "size" : "1024x1024", 149 | "idiom" : "ios-marketing", 150 | "filename" : "icon-1024@2x.png", 151 | "scale" : "1x" 152 | } 153 | ], 154 | "info" : { 155 | "version" : 1, 156 | "author" : "xcode" 157 | } 158 | } -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-1024@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-1024@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-29.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-40.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-50.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-57.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-72.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-76.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitWOSBiOS56_768x1004pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitWOSBiOS56_768x1004pt.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitWOSBiOS56_768x1004pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitWOSBiOS56_768x1004pt@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitiOS56_768x1024pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitiOS56_768x1024pt.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitiOS56_768x1024pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitiOS56_768x1024pt@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitiOS789_768x1024pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitiOS789_768x1024pt.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitiOS789_768x1024pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPadPortraitiOS789_768x1024pt@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS56_320x480pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS56_320x480pt.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS56_320x480pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS56_320x480pt@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS56_320x568pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS56_320x568pt@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS789_320x480pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS789_320x480pt@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS789_320x568pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS789_320x568pt@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS89_375x667pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS89_375x667pt@2x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS89_414x736pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/1024iPhonePortraitiOS89_414x736pt@3x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "extent" : "full-screen", 5 | "idiom" : "iphone", 6 | "subtype" : "736h", 7 | "filename" : "1024iPhonePortraitiOS89_414x736pt@3x.png", 8 | "minimum-system-version" : "8.0", 9 | "orientation" : "portrait", 10 | "scale" : "3x" 11 | }, 12 | { 13 | "extent" : "full-screen", 14 | "idiom" : "iphone", 15 | "subtype" : "667h", 16 | "filename" : "1024iPhonePortraitiOS89_375x667pt@2x.png", 17 | "minimum-system-version" : "8.0", 18 | "orientation" : "portrait", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "orientation" : "portrait", 23 | "idiom" : "iphone", 24 | "filename" : "1024iPhonePortraitiOS789_320x480pt@2x.png", 25 | "extent" : "full-screen", 26 | "minimum-system-version" : "7.0", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "extent" : "full-screen", 31 | "idiom" : "iphone", 32 | "subtype" : "retina4", 33 | "filename" : "1024iPhonePortraitiOS789_320x568pt@2x.png", 34 | "minimum-system-version" : "7.0", 35 | "orientation" : "portrait", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "orientation" : "portrait", 40 | "idiom" : "ipad", 41 | "filename" : "1024iPadPortraitiOS789_768x1024pt.png", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "1x" 45 | }, 46 | { 47 | "orientation" : "portrait", 48 | "idiom" : "ipad", 49 | "filename" : "1024iPadPortraitiOS789_768x1024pt@2x.png", 50 | "extent" : "full-screen", 51 | "minimum-system-version" : "7.0", 52 | "scale" : "2x" 53 | }, 54 | { 55 | "orientation" : "portrait", 56 | "idiom" : "iphone", 57 | "filename" : "1024iPhonePortraitiOS56_320x480pt.png", 58 | "extent" : "full-screen", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "orientation" : "portrait", 63 | "idiom" : "iphone", 64 | "filename" : "1024iPhonePortraitiOS56_320x480pt@2x.png", 65 | "extent" : "full-screen", 66 | "scale" : "2x" 67 | }, 68 | { 69 | "orientation" : "portrait", 70 | "idiom" : "iphone", 71 | "filename" : "1024iPhonePortraitiOS56_320x568pt@2x.png", 72 | "extent" : "full-screen", 73 | "subtype" : "retina4", 74 | "scale" : "2x" 75 | }, 76 | { 77 | "orientation" : "portrait", 78 | "idiom" : "ipad", 79 | "filename" : "1024iPadPortraitWOSBiOS56_768x1004pt.png", 80 | "extent" : "to-status-bar", 81 | "scale" : "1x" 82 | }, 83 | { 84 | "orientation" : "portrait", 85 | "idiom" : "ipad", 86 | "filename" : "1024iPadPortraitiOS56_768x1024pt.png", 87 | "extent" : "full-screen", 88 | "scale" : "1x" 89 | }, 90 | { 91 | "orientation" : "portrait", 92 | "idiom" : "ipad", 93 | "filename" : "1024iPadPortraitWOSBiOS56_768x1004pt@2x.png", 94 | "extent" : "to-status-bar", 95 | "scale" : "2x" 96 | }, 97 | { 98 | "orientation" : "portrait", 99 | "idiom" : "ipad", 100 | "filename" : "1024iPadPortraitiOS56_768x1024pt@2x.png", 101 | "extent" : "full-screen", 102 | "scale" : "2x" 103 | } 104 | ], 105 | "info" : { 106 | "version" : 1, 107 | "author" : "xcode" 108 | } 109 | } -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/parallax_back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "parallax_back@3x.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/parallax_back.imageset/parallax_back@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/parallax_back.imageset/parallax_back@3x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/parallax_front.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "parallax_front@3x.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/parallax_front.imageset/parallax_front@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/parallax_front.imageset/parallax_front@3x.png -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/parallax_middle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "parallax_middle@3x.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MSParallaxDemo/Assets.xcassets/parallax_middle.imageset/parallax_middle@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tempAccountA/MSParallaxDemo/97822dae5343c3320a7138651ecb7ccbd97dff82/MSParallaxDemo/Assets.xcassets/parallax_middle.imageset/parallax_middle@3x.png -------------------------------------------------------------------------------- /MSParallaxDemo/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 | NSAppTransportSecurity 24 | 25 | NSAllowsArbitraryLoads 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UISupportedInterfaceOrientations 35 | 36 | UIInterfaceOrientationPortrait 37 | 38 | UISupportedInterfaceOrientations~ipad 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationPortraitUpsideDown 42 | UIInterfaceOrientationLandscapeLeft 43 | UIInterfaceOrientationLandscapeRight 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /MSParallaxDemo/MSParallaxViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxViewController.h 3 | // 4 | // 5 | // Created by JZJ on 2019/5/29. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface MSParallaxViewController : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /MSParallaxDemo/MSParallaxViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxViewController.m 3 | // 4 | // 5 | // Created by JZJ on 2019/5/29. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import "MSParallaxViewController.h" 10 | #import "MSParallaxHorizonFlowLayout.h" 11 | #import "MSParallaxAnimationCell.h" 12 | 13 | #import "MSParallaxCollectionViewBack.h" 14 | #import "MSParallaxCollectionViewMiddle.h" 15 | #import "MSParallaxCollectionViewFront.h" 16 | 17 | //速度调整 18 | static CGFloat const backSpeed = 5; 19 | static CGFloat const middleSpeed = 10; 20 | static CGFloat const frontSpeed = 15; 21 | 22 | @interface MSParallaxViewController () 24 | 25 | @property(nonatomic,strong) NSMutableArray *backDataArray; 26 | @property(nonatomic,strong) NSMutableArray *middleDataArray; 27 | @property(nonatomic,strong) NSMutableArray *frontArray; 28 | 29 | 30 | @property (nonatomic, strong) MSParallaxCollectionViewBack *backCollectionView; 31 | @property (nonatomic, strong) MSParallaxCollectionViewMiddle *middleCollectionView; 32 | @property (nonatomic, strong) MSParallaxCollectionViewFront *frontCollectionView; 33 | 34 | @property (nonatomic,strong)NSTimer *timer; 35 | 36 | @end 37 | 38 | @implementation MSParallaxViewController 39 | 40 | 41 | - (void)viewDidLoad { 42 | [super viewDidLoad]; 43 | 44 | //UI布局 45 | [self setupUI]; 46 | 47 | //请求数据 48 | [self requestData]; 49 | 50 | } 51 | 52 | //ui布局 53 | -(void)setupUI{ 54 | [self.view addSubview:self.backCollectionView]; 55 | [self.view addSubview:self.middleCollectionView]; 56 | [self.view addSubview:self.frontCollectionView]; 57 | } 58 | 59 | 60 | //代理返回值 61 | -(void)requestData{ 62 | 63 | for (NSInteger i = 0; i<1000; i++) { 64 | [self.backDataArray addObject:@"parallax_back"]; 65 | [self.middleDataArray addObject:@"parallax_middle"]; 66 | [self.frontArray addObject:@"parallax_front"]; 67 | if(i==1000-1){ 68 | [self reloadData]; 69 | } 70 | } 71 | } 72 | 73 | 74 | -(void)reloadData{ 75 | 76 | [self.backCollectionView reloadData]; 77 | self.middleCollectionView.dataArray = self.middleDataArray; 78 | [self.middleCollectionView reloadData]; 79 | self.frontCollectionView.dataArray = self.frontArray; 80 | [self.frontCollectionView reloadData]; 81 | [self.timer setFireDate:[NSDate date]]; 82 | } 83 | 84 | 85 | 86 | #pragma mark --collectionViewDataSource 87 | 88 | - (NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 89 | return self.backDataArray.count; 90 | } 91 | 92 | - (UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 93 | NSString* url = self.backDataArray[indexPath.item]; 94 | MSParallaxAnimationCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MSParallaxAnimationCell" forIndexPath:indexPath]; 95 | cell.imageUrl = url; 96 | cell.contentView.backgroundColor = [UIColor clearColor]; 97 | return cell; 98 | } 99 | 100 | #pragma mark --lazy 101 | 102 | 103 | - (NSMutableArray *)backDataArray{ 104 | if(!_backDataArray){ 105 | _backDataArray = [NSMutableArray array]; 106 | } 107 | return _backDataArray; 108 | } 109 | 110 | - (NSMutableArray *)middleDataArray{ 111 | if(!_middleDataArray){ 112 | _middleDataArray = [NSMutableArray array]; 113 | } 114 | return _middleDataArray; 115 | } 116 | 117 | - (NSMutableArray *)frontArray{ 118 | if(!_frontArray){ 119 | _frontArray = [NSMutableArray array]; 120 | } 121 | return _frontArray; 122 | } 123 | 124 | 125 | 126 | - (UICollectionView *)backCollectionView{ 127 | if (!_backCollectionView) { 128 | 129 | CGFloat width = [UIScreen mainScreen].bounds.size.width; 130 | CGFloat height = [UIScreen mainScreen].bounds.size.height; 131 | 132 | MSParallaxHorizonFlowLayout *layout = [[MSParallaxHorizonFlowLayout alloc] init]; 133 | CGFloat W = width; 134 | CGFloat H = height; 135 | layout.scrollDirection = 1; //左右滚动 136 | layout.size = CGSizeMake(W, H); 137 | layout.columnSpacing = 0; 138 | layout.rowSpacing = 2; 139 | layout.row = 1; 140 | layout.column = 1; 141 | layout.showLastPageFull = NO; // 不完全展示最后一页 142 | layout.pageWidth = width; 143 | layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0); 144 | 145 | _backCollectionView = [[MSParallaxCollectionViewBack alloc] initWithFrame:CGRectMake(0, 0, layout.collectionViewSize.width, layout.collectionViewSize.height) collectionViewLayout:layout]; 146 | _backCollectionView.delegate = self; 147 | _backCollectionView.dataSource = self; 148 | _backCollectionView.showsHorizontalScrollIndicator = NO; 149 | _backCollectionView.pagingEnabled = YES; 150 | [_backCollectionView registerClass:[MSParallaxAnimationCell class] forCellWithReuseIdentifier:@"MSParallaxAnimationCell"]; 151 | _backCollectionView.backgroundColor = [UIColor clearColor]; 152 | _backCollectionView.frame = self.view.bounds; 153 | _backCollectionView.pagingEnabled = NO; 154 | _backCollectionView.userInteractionEnabled = NO; 155 | 156 | } 157 | return _backCollectionView; 158 | } 159 | 160 | 161 | - (MSParallaxCollectionViewMiddle *)middleCollectionView{ 162 | if (!_middleCollectionView) { 163 | 164 | CGFloat width = [UIScreen mainScreen].bounds.size.width; 165 | CGFloat height = [UIScreen mainScreen].bounds.size.height; 166 | 167 | MSParallaxHorizonFlowLayout *layout = [[MSParallaxHorizonFlowLayout alloc] init]; 168 | CGFloat W = width; 169 | CGFloat H = height*0.6; 170 | layout.scrollDirection = 1; //左右滚动 171 | layout.size = CGSizeMake(W, H); 172 | layout.columnSpacing = 0; 173 | layout.rowSpacing = 2; 174 | layout.row = 1; 175 | layout.column = 4; 176 | layout.showLastPageFull = NO; // 不完全展示最后一页 177 | layout.pageWidth = width; 178 | 179 | layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0); 180 | 181 | _middleCollectionView = [[MSParallaxCollectionViewMiddle alloc] initWithFrame:CGRectMake(0, 100, layout.collectionViewSize.width, layout.collectionViewSize.height) collectionViewLayout:layout]; 182 | _middleCollectionView.delegate = _middleCollectionView; 183 | _middleCollectionView.dataSource = _middleCollectionView; 184 | _middleCollectionView.showsHorizontalScrollIndicator = NO; 185 | _middleCollectionView.pagingEnabled = YES; 186 | [_middleCollectionView registerClass:[MSParallaxAnimationCell class] forCellWithReuseIdentifier:@"MSParallaxAnimationCell"]; 187 | _middleCollectionView.backgroundColor = [UIColor clearColor]; 188 | _middleCollectionView.frame = CGRectMake(0, height-H, self.view.bounds.size.width, H); 189 | _middleCollectionView.pagingEnabled = NO; 190 | _middleCollectionView.userInteractionEnabled = NO; 191 | 192 | } 193 | return _middleCollectionView; 194 | } 195 | 196 | 197 | 198 | 199 | - (MSParallaxCollectionViewFront *)frontCollectionView{ 200 | if (!_frontCollectionView) { 201 | 202 | CGFloat width = [UIScreen mainScreen].bounds.size.width; 203 | CGFloat height = [UIScreen mainScreen].bounds.size.height; 204 | 205 | MSParallaxHorizonFlowLayout *layout = [[MSParallaxHorizonFlowLayout alloc] init]; 206 | CGFloat W = width; 207 | CGFloat H = height; 208 | layout.scrollDirection = 1; //左右滚动 209 | layout.size = CGSizeMake(W, H); 210 | layout.columnSpacing = 0; 211 | layout.rowSpacing = 2; 212 | layout.row = 3; 213 | layout.column = 4; 214 | layout.showLastPageFull = NO; // 不完全展示最后一页 215 | layout.pageWidth = width; 216 | layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0); 217 | 218 | _frontCollectionView = [[MSParallaxCollectionViewFront alloc] initWithFrame:CGRectMake(0, 100, layout.collectionViewSize.width, layout.collectionViewSize.height) collectionViewLayout:layout]; 219 | _frontCollectionView.delegate = _frontCollectionView; 220 | _frontCollectionView.dataSource = _frontCollectionView; 221 | _frontCollectionView.frame = self.view.bounds; 222 | _frontCollectionView.showsHorizontalScrollIndicator = NO; 223 | _frontCollectionView.pagingEnabled = YES; 224 | [_frontCollectionView registerClass:[MSParallaxAnimationCell class] forCellWithReuseIdentifier:@"MSParallaxAnimationCell"]; 225 | _frontCollectionView.backgroundColor = [UIColor clearColor]; 226 | _frontCollectionView.pagingEnabled = NO; 227 | _frontCollectionView.userInteractionEnabled = NO; 228 | } 229 | return _frontCollectionView; 230 | } 231 | 232 | - (NSTimer *)timer{ 233 | if(!_timer){ 234 | _timer = [NSTimer timerWithTimeInterval:1/20.0 target:self selector:@selector(backTimer) userInfo:nil repeats:YES]; 235 | [_timer setFireDate:[NSDate distantFuture]]; 236 | [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes]; 237 | 238 | } 239 | return _timer; 240 | } 241 | 242 | -(void)destroyTimer{ 243 | 244 | [self.timer invalidate]; 245 | } 246 | 247 | //速度调整 248 | - (void)backTimer{ 249 | self.backCollectionView.contentOffset = CGPointMake(self.backCollectionView.contentOffset.x+backSpeed, 0); 250 | 251 | self.middleCollectionView.contentOffset = CGPointMake(self.middleCollectionView.contentOffset.x+middleSpeed, 0); 252 | 253 | self.frontCollectionView.contentOffset = CGPointMake(self.frontCollectionView.contentOffset.x+frontSpeed, 0); 254 | } 255 | 256 | - (void)viewDidDisappear:(BOOL)animated{ 257 | [self destroyTimer]; 258 | } 259 | 260 | @end 261 | -------------------------------------------------------------------------------- /MSParallaxDemo/animationView/MSParallaxAnimationCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxAnimationCell.h 3 | // 4 | // 5 | // Created by JZJ on 2019/4/22. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface MSParallaxAnimationCell : UICollectionViewCell 14 | @property (nonatomic, copy) NSString *imageUrl; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /MSParallaxDemo/animationView/MSParallaxAnimationCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxAnimationCell.m 3 | // 4 | // 5 | // Created by JZJ on 2019/4/22. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import "MSParallaxAnimationCell.h" 10 | 11 | @interface MSParallaxAnimationCell() 12 | 13 | @property(nonatomic,strong)UIImageView* imageView; 14 | 15 | @end 16 | 17 | @implementation MSParallaxAnimationCell 18 | 19 | - (void)setImageUrl:(NSString *)imageUrl{ 20 | 21 | self.imageView.image = [UIImage imageNamed:imageUrl]; 22 | } 23 | 24 | -(UIImageView *)imageView{ 25 | if(!_imageView){ 26 | _imageView= [UIImageView new]; 27 | _imageView.frame = self.bounds; 28 | [self.contentView addSubview:_imageView]; 29 | } 30 | return _imageView; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /MSParallaxDemo/animationView/MSParallaxCollectionViewBack.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxCollectionViewBack.h 3 | // 4 | // 5 | // Created by JZJ on 29/5/2019. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface MSParallaxCollectionViewBack : UICollectionView 14 | 15 | @property(nonatomic,strong)NSMutableArray* dataArray; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /MSParallaxDemo/animationView/MSParallaxCollectionViewBack.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxCollectionViewBack 3 | // 4 | // 5 | // Created by JZJ on 29/5/2019. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import "MSParallaxCollectionViewBack.h" 10 | #import "MSParallaxAnimationCell.h" 11 | 12 | @implementation MSParallaxCollectionViewBack 13 | 14 | 15 | - (NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 16 | return self.dataArray.count; 17 | } 18 | 19 | - (UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 20 | NSString* url = self.dataArray[indexPath.item]; 21 | MSParallaxAnimationCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MSParallaxAnimationCell" forIndexPath:indexPath]; 22 | cell.imageUrl = url; 23 | return cell; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /MSParallaxDemo/animationView/MSParallaxCollectionViewFront.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxCollectionViewFront.h 3 | // 4 | // 5 | // Created by on 29/5/2019. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface MSParallaxCollectionViewFront : UICollectionView 14 | @property(nonatomic,strong)NSMutableArray* dataArray; 15 | 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /MSParallaxDemo/animationView/MSParallaxCollectionViewFront.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxCollectionViewFront.m 3 | // 4 | // 5 | // Created by on 29/5/2019. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import "MSParallaxCollectionViewFront.h" 10 | #import "MSParallaxAnimationCell.h" 11 | 12 | @implementation MSParallaxCollectionViewFront 13 | 14 | 15 | - (NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 16 | return self.dataArray.count; 17 | } 18 | - (UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 19 | NSString* url = self.dataArray[indexPath.item]; 20 | MSParallaxAnimationCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MSParallaxAnimationCell" forIndexPath:indexPath]; 21 | cell.imageUrl = url; 22 | return cell; 23 | } 24 | 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /MSParallaxDemo/animationView/MSParallaxCollectionViewMiddle.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxCollectionViewMiddle.h 3 | // 4 | // 5 | // Created by on 29/5/2019. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface MSParallaxCollectionViewMiddle : UICollectionView 15 | 16 | @property(nonatomic,strong)NSMutableArray* dataArray; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /MSParallaxDemo/animationView/MSParallaxCollectionViewMiddle.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxCollectionViewMiddle.m 3 | // 4 | // 5 | // Created by on 29/5/2019. 6 | // Copyright © 2019 JZJ. All rights reserved. 7 | // 8 | 9 | #import "MSParallaxCollectionViewMiddle.h" 10 | #import "MSParallaxAnimationCell.h" 11 | 12 | @implementation MSParallaxCollectionViewMiddle 13 | 14 | 15 | - (NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 16 | return self.dataArray.count; 17 | } 18 | 19 | - (UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 20 | NSString* url = self.dataArray[indexPath.item]; 21 | MSParallaxAnimationCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MSParallaxAnimationCell" forIndexPath:indexPath]; 22 | cell.imageUrl = url; 23 | return cell; 24 | } 25 | 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /MSParallaxDemo/animationView/MSParallaxHorizonFlowLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxHorizonFlowLayout.h 3 | // 4 | // 5 | // Created by JZJ on 2017/9/13. 6 | // Copyright © 2017年 JZJ. All rights reserved. 7 | // 8 | // MIT License 9 | // 10 | // Copyright (c) 2017 xjh093 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in all 20 | // copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | // SOFTWARE. 29 | 30 | #import 31 | 32 | @interface MSParallaxHorizonFlowLayout : UICollectionViewFlowLayout 33 | ///一页展示行数 34 | @property (nonatomic, assign) NSInteger row; 35 | ///一页展示列数 36 | @property (nonatomic, assign) NSInteger column; 37 | ///行间距 38 | @property (nonatomic, assign) CGFloat rowSpacing; 39 | ///列间距 40 | @property (nonatomic, assign) CGFloat columnSpacing; 41 | ///item大小 42 | @property (nonatomic, assign) CGSize size; 43 | ///一页的宽度,默认 [UIScreen mainScreen].bounds.size.width 44 | @property (nonatomic, assign) CGFloat pageWidth; 45 | ///默认YES。根据最后一页的个数,是否展示完整的一页 46 | @property (nonatomic, assign) BOOL showLastPageFull; 47 | ///collectionView Size 48 | @property (nonatomic, assign, readonly) CGSize collectionViewSize; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /MSParallaxDemo/animationView/MSParallaxHorizonFlowLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSParallaxHorizonFlowLayout.m 3 | // 4 | // 5 | // Created by JZJ on 2017/9/13. 6 | // Copyright © 2017年 JZJ. All rights reserved. 7 | // 8 | // MIT License 9 | // 10 | // Copyright (c) 2017 xjh093 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in all 20 | // copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | // SOFTWARE. 29 | 30 | #import "MSParallaxHorizonFlowLayout.h" 31 | 32 | @interface MSParallaxHorizonFlowLayout() 33 | @property (strong, nonatomic) NSMutableArray *attributesArray; 34 | @property (nonatomic, assign) CGFloat onePageWidth; 35 | @end 36 | 37 | @implementation MSParallaxHorizonFlowLayout 38 | 39 | - (instancetype)init 40 | { 41 | self = [super init]; 42 | if (self) { 43 | _showLastPageFull = YES; 44 | _pageWidth = [UIScreen mainScreen].bounds.size.width; 45 | } 46 | return self; 47 | } 48 | 49 | - (void)prepareLayout 50 | { 51 | [super prepareLayout]; 52 | 53 | _attributesArray = @[].mutableCopy; 54 | _onePageWidth = (_size.width + _columnSpacing) * _column - _columnSpacing; 55 | 56 | NSUInteger count = [self.collectionView numberOfItemsInSection:0]; 57 | for (NSUInteger i = 0; i < count; i++) { 58 | NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0]; 59 | UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath]; 60 | [_attributesArray addObject:attributes]; 61 | } 62 | } 63 | 64 | //计算每个item的frame 65 | - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{ 66 | UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 67 | 68 | NSInteger index = indexPath.item; 69 | 70 | NSInteger page = index / (_row * _column); 71 | 72 | // % 运算 确定 x 是 0,1,2 ... _column-1 73 | CGFloat x = (index % _column) * (_size.width + _columnSpacing) + page * (_onePageWidth + _columnSpacing) + self.sectionInset.left; 74 | // / 运算 确定 y 是 在哪行(一行有 column 个), % 确定在 0,1,2 ... _row-1 行内的哪行 75 | CGFloat y = (index / _column % _row) * (_size.height + _rowSpacing) + self.sectionInset.top; 76 | 77 | attribute.frame = CGRectMake(x, y, _size.width, _size.height); 78 | 79 | return attribute; 80 | 81 | } 82 | 83 | //返回所有item的frame 84 | - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{ 85 | return _attributesArray; 86 | } 87 | 88 | //返回总的可见尺寸 89 | //避免一页未排满,滑动显示不全 90 | - (CGSize)collectionViewContentSize{ 91 | CGFloat width = (CGFloat)ceil(_attributesArray.count/(_row * _column * 1.0)) * _onePageWidth; 92 | if (!_showLastPageFull) { 93 | NSInteger lastCount = _attributesArray.count%(_row * _column); 94 | if (lastCount > 0 && lastCount < _column) { 95 | width = _attributesArray.count/(_row * _column) * _onePageWidth; 96 | width += (_size.width + _columnSpacing)*lastCount; 97 | } 98 | } 99 | width += self.sectionInset.left + self.sectionInset.right; 100 | CGFloat height = (_size.height + _rowSpacing) * _row + self.sectionInset.top + self.sectionInset.bottom; 101 | return CGSizeMake(width, height); 102 | } 103 | 104 | - (CGSize)collectionViewSize 105 | { 106 | return CGSizeMake(_pageWidth, (_size.height + _rowSpacing) * _row + self.sectionInset.top + self.sectionInset.bottom); 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /MSParallaxDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // 4 | // 5 | // Created by JZJ on 2019/5/29. 6 | // Copyright © 2019 JZJ. 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 | #MSParallaxDemo 2 | 3 | ![image](MSParallaxDemo.gif) 4 | 5 | --------------------------------------------------------------------------------