├── .gitignore ├── .swift-version ├── .travis.yml ├── Assets ├── animation.gif ├── screenshot1.png └── screenshot2.png ├── LICENSE ├── RAReorderableLayout-Demo ├── RAReorderableLayout-Demo.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── RAReorderableLayout-Demo │ ├── AppDelegate.swift │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── HorizontalViewController.swift │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── LaunchImage.launchimage │ │ │ └── Contents.json │ │ └── sample │ │ │ ├── Sample0.imageset │ │ │ ├── Contents.json │ │ │ └── Sample0.jpg │ │ │ ├── Sample1.imageset │ │ │ ├── Contents.json │ │ │ └── Sample1.jpg │ │ │ ├── Sample10.imageset │ │ │ ├── Contents.json │ │ │ └── Sample10.jpg │ │ │ ├── Sample11.imageset │ │ │ ├── Contents.json │ │ │ └── Sample11.jpg │ │ │ ├── Sample12.imageset │ │ │ ├── Contents.json │ │ │ └── Sample12.jpg │ │ │ ├── Sample13.imageset │ │ │ ├── Contents.json │ │ │ └── Sample13.jpg │ │ │ ├── Sample14.imageset │ │ │ ├── Contents.json │ │ │ └── Sample14.jpg │ │ │ ├── Sample15.imageset │ │ │ ├── Contents.json │ │ │ └── Sample15.jpg │ │ │ ├── Sample16.imageset │ │ │ ├── Contents.json │ │ │ └── Sample16.jpg │ │ │ ├── Sample17.imageset │ │ │ ├── Contents.json │ │ │ └── Sample17.jpg │ │ │ ├── Sample18.imageset │ │ │ ├── Contents.json │ │ │ └── Sample18.jpg │ │ │ ├── Sample19.imageset │ │ │ ├── Contents.json │ │ │ └── Sample19.jpg │ │ │ ├── Sample2.imageset │ │ │ ├── Contents.json │ │ │ └── Sample2.jpg │ │ │ ├── Sample20.imageset │ │ │ ├── Contents.json │ │ │ └── Sample20.jpg │ │ │ ├── Sample21.imageset │ │ │ ├── Contents.json │ │ │ └── Sample21.jpg │ │ │ ├── Sample22.imageset │ │ │ ├── Contents.json │ │ │ └── Sample22.jpg │ │ │ ├── Sample23.imageset │ │ │ ├── Contents.json │ │ │ └── Sample23.jpg │ │ │ ├── Sample24.imageset │ │ │ ├── Contents.json │ │ │ └── Sample24.jpg │ │ │ ├── Sample25.imageset │ │ │ ├── Contents.json │ │ │ └── Sample25.jpg │ │ │ ├── Sample26.imageset │ │ │ ├── Contents.json │ │ │ └── Sample26.jpg │ │ │ ├── Sample27.imageset │ │ │ ├── Contents.json │ │ │ └── Sample27.jpg │ │ │ ├── Sample28.imageset │ │ │ ├── Contents.json │ │ │ └── Sample28.jpg │ │ │ ├── Sample29.imageset │ │ │ ├── Contents.json │ │ │ └── Sample29.jpg │ │ │ ├── Sample3.imageset │ │ │ ├── Contents.json │ │ │ └── Sample3.jpg │ │ │ ├── Sample4.imageset │ │ │ ├── Contents.json │ │ │ └── Sample4.jpg │ │ │ ├── Sample5.imageset │ │ │ ├── Contents.json │ │ │ └── Sample5.jpg │ │ │ ├── Sample6.imageset │ │ │ ├── Contents.json │ │ │ └── Sample6.jpg │ │ │ ├── Sample7.imageset │ │ │ ├── Contents.json │ │ │ └── Sample7.jpg │ │ │ ├── Sample8.imageset │ │ │ ├── Contents.json │ │ │ └── Sample8.jpg │ │ │ └── Sample9.imageset │ │ │ ├── Contents.json │ │ │ └── Sample9.jpg │ ├── Info.plist │ ├── Main.storyboard │ ├── RAReorderableLayout_Demo.xcdatamodeld │ │ ├── .xccurrentversion │ │ └── RAReorderableLayout_Demo.xcdatamodel │ │ │ └── contents │ ├── VerticalViewController.swift │ └── ViewController.swift └── RAReorderableLayout-DemoTests │ ├── Info.plist │ └── RAReorderableLayout_DemoTests.swift ├── RAReorderableLayout.podspec ├── RAReorderableLayout.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── RAReorderableLayout.xcscheme ├── RAReorderableLayout ├── Info.plist ├── RAReorderableLayout.h └── RAReorderableLayout.swift └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # We recommend against adding the Pods directory to your .gitignore. However 26 | # you should judge for yourself, the pros and cons are mentioned at: 27 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 28 | # 29 | # Note: if you ignore the Pods directory, make sure to uncomment 30 | # `pod install` in .travis.yml 31 | # 32 | # Pods/ 33 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # reference: http://www.objc.io/issue-6/travis-ci.html 2 | 3 | language: objective-c 4 | # before_install: cd Example && pod install && cd - 5 | script: 6 | - xctool test -workspace Example/RAReorderableLayout.xcworkspace -scheme RAReorderableLayout -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO 7 | -------------------------------------------------------------------------------- /Assets/animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/Assets/animation.gif -------------------------------------------------------------------------------- /Assets/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/Assets/screenshot1.png -------------------------------------------------------------------------------- /Assets/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/Assets/screenshot2.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 ra1028 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. -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2A972DBE1A195D940084B0D5 /* VerticalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A972DBD1A195D930084B0D5 /* VerticalViewController.swift */; }; 11 | 2A972DC01A195F0C0084B0D5 /* HorizontalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A972DBF1A195F0C0084B0D5 /* HorizontalViewController.swift */; }; 12 | 2A972DC21A1961BF0084B0D5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A972DC11A1961BF0084B0D5 /* Main.storyboard */; }; 13 | 2AF54EDC1A002CD1007A7144 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF54EDB1A002CD1007A7144 /* AppDelegate.swift */; }; 14 | 2AF54EDF1A002CD1007A7144 /* RAReorderableLayout_Demo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 2AF54EDD1A002CD1007A7144 /* RAReorderableLayout_Demo.xcdatamodeld */; }; 15 | 2AF54EE11A002CD1007A7144 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF54EE01A002CD1007A7144 /* ViewController.swift */; }; 16 | 2AF54EE61A002CD1007A7144 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2AF54EE51A002CD1007A7144 /* Images.xcassets */; }; 17 | 2AF54F031A002D2B007A7144 /* RAReorderableLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF54F021A002D2B007A7144 /* RAReorderableLayout.swift */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 2A972DBD1A195D930084B0D5 /* VerticalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = VerticalViewController.swift; sourceTree = ""; tabWidth = 4; }; 22 | 2A972DBF1A195F0C0084B0D5 /* HorizontalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = HorizontalViewController.swift; sourceTree = ""; tabWidth = 4; }; 23 | 2A972DC11A1961BF0084B0D5 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 24 | 2AF54ED61A002CD1007A7144 /* RAReorderableLayout-Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "RAReorderableLayout-Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 2AF54EDA1A002CD1007A7144 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 26 | 2AF54EDB1A002CD1007A7144 /* AppDelegate.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; tabWidth = 4; }; 27 | 2AF54EDE1A002CD1007A7144 /* RAReorderableLayout_Demo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = RAReorderableLayout_Demo.xcdatamodel; sourceTree = ""; }; 28 | 2AF54EE01A002CD1007A7144 /* ViewController.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; tabWidth = 4; }; 29 | 2AF54EE51A002CD1007A7144 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 30 | 2AF54EE81A002CD1007A7144 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 31 | 2AF54EF31A002CD1007A7144 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | 2AF54EF41A002CD1007A7144 /* RAReorderableLayout_DemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RAReorderableLayout_DemoTests.swift; sourceTree = ""; }; 33 | 2AF54F021A002D2B007A7144 /* RAReorderableLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RAReorderableLayout.swift; sourceTree = ""; }; 34 | /* End PBXFileReference section */ 35 | 36 | /* Begin PBXFrameworksBuildPhase section */ 37 | 2AF54ED31A002CD1007A7144 /* Frameworks */ = { 38 | isa = PBXFrameworksBuildPhase; 39 | buildActionMask = 2147483647; 40 | files = ( 41 | ); 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | /* End PBXFrameworksBuildPhase section */ 45 | 46 | /* Begin PBXGroup section */ 47 | 2AF54ECD1A002CD1007A7144 = { 48 | isa = PBXGroup; 49 | children = ( 50 | 2AF54F011A002D2B007A7144 /* RAReorderableLayout */, 51 | 2AF54ED81A002CD1007A7144 /* RAReorderableLayout-Demo */, 52 | 2AF54EF11A002CD1007A7144 /* RAReorderableLayout-DemoTests */, 53 | 2AF54ED71A002CD1007A7144 /* Products */, 54 | ); 55 | sourceTree = ""; 56 | }; 57 | 2AF54ED71A002CD1007A7144 /* Products */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | 2AF54ED61A002CD1007A7144 /* RAReorderableLayout-Demo.app */, 61 | ); 62 | name = Products; 63 | sourceTree = ""; 64 | }; 65 | 2AF54ED81A002CD1007A7144 /* RAReorderableLayout-Demo */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 2AF54EDB1A002CD1007A7144 /* AppDelegate.swift */, 69 | 2AF54EE01A002CD1007A7144 /* ViewController.swift */, 70 | 2A972DBD1A195D930084B0D5 /* VerticalViewController.swift */, 71 | 2A972DBF1A195F0C0084B0D5 /* HorizontalViewController.swift */, 72 | 2A972DC11A1961BF0084B0D5 /* Main.storyboard */, 73 | 2AF54EE51A002CD1007A7144 /* Images.xcassets */, 74 | 2AF54EE71A002CD1007A7144 /* LaunchScreen.xib */, 75 | 2AF54EDD1A002CD1007A7144 /* RAReorderableLayout_Demo.xcdatamodeld */, 76 | 2AF54ED91A002CD1007A7144 /* Supporting Files */, 77 | ); 78 | path = "RAReorderableLayout-Demo"; 79 | sourceTree = ""; 80 | }; 81 | 2AF54ED91A002CD1007A7144 /* Supporting Files */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 2AF54EDA1A002CD1007A7144 /* Info.plist */, 85 | ); 86 | name = "Supporting Files"; 87 | sourceTree = ""; 88 | }; 89 | 2AF54EF11A002CD1007A7144 /* RAReorderableLayout-DemoTests */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 2AF54EF41A002CD1007A7144 /* RAReorderableLayout_DemoTests.swift */, 93 | 2AF54EF21A002CD1007A7144 /* Supporting Files */, 94 | ); 95 | path = "RAReorderableLayout-DemoTests"; 96 | sourceTree = ""; 97 | }; 98 | 2AF54EF21A002CD1007A7144 /* Supporting Files */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 2AF54EF31A002CD1007A7144 /* Info.plist */, 102 | ); 103 | name = "Supporting Files"; 104 | sourceTree = ""; 105 | }; 106 | 2AF54F011A002D2B007A7144 /* RAReorderableLayout */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 2AF54F021A002D2B007A7144 /* RAReorderableLayout.swift */, 110 | ); 111 | name = RAReorderableLayout; 112 | path = ../RAReorderableLayout; 113 | sourceTree = ""; 114 | }; 115 | /* End PBXGroup section */ 116 | 117 | /* Begin PBXNativeTarget section */ 118 | 2AF54ED51A002CD1007A7144 /* RAReorderableLayout-Demo */ = { 119 | isa = PBXNativeTarget; 120 | buildConfigurationList = 2AF54EF81A002CD1007A7144 /* Build configuration list for PBXNativeTarget "RAReorderableLayout-Demo" */; 121 | buildPhases = ( 122 | 2AF54ED21A002CD1007A7144 /* Sources */, 123 | 2AF54ED31A002CD1007A7144 /* Frameworks */, 124 | 2AF54ED41A002CD1007A7144 /* Resources */, 125 | ); 126 | buildRules = ( 127 | ); 128 | dependencies = ( 129 | ); 130 | name = "RAReorderableLayout-Demo"; 131 | productName = "RAReorderableLayout-Demo"; 132 | productReference = 2AF54ED61A002CD1007A7144 /* RAReorderableLayout-Demo.app */; 133 | productType = "com.apple.product-type.application"; 134 | }; 135 | /* End PBXNativeTarget section */ 136 | 137 | /* Begin PBXProject section */ 138 | 2AF54ECE1A002CD1007A7144 /* Project object */ = { 139 | isa = PBXProject; 140 | attributes = { 141 | LastSwiftUpdateCheck = 0730; 142 | LastUpgradeCheck = 0800; 143 | ORGANIZATIONNAME = "Ryo Aoyama"; 144 | TargetAttributes = { 145 | 2AF54ED51A002CD1007A7144 = { 146 | CreatedOnToolsVersion = 6.1; 147 | LastSwiftMigration = 0800; 148 | }; 149 | }; 150 | }; 151 | buildConfigurationList = 2AF54ED11A002CD1007A7144 /* Build configuration list for PBXProject "RAReorderableLayout-Demo" */; 152 | compatibilityVersion = "Xcode 3.2"; 153 | developmentRegion = English; 154 | hasScannedForEncodings = 0; 155 | knownRegions = ( 156 | en, 157 | Base, 158 | ); 159 | mainGroup = 2AF54ECD1A002CD1007A7144; 160 | productRefGroup = 2AF54ED71A002CD1007A7144 /* Products */; 161 | projectDirPath = ""; 162 | projectRoot = ""; 163 | targets = ( 164 | 2AF54ED51A002CD1007A7144 /* RAReorderableLayout-Demo */, 165 | ); 166 | }; 167 | /* End PBXProject section */ 168 | 169 | /* Begin PBXResourcesBuildPhase section */ 170 | 2AF54ED41A002CD1007A7144 /* Resources */ = { 171 | isa = PBXResourcesBuildPhase; 172 | buildActionMask = 2147483647; 173 | files = ( 174 | 2AF54EE61A002CD1007A7144 /* Images.xcassets in Resources */, 175 | 2A972DC21A1961BF0084B0D5 /* Main.storyboard in Resources */, 176 | ); 177 | runOnlyForDeploymentPostprocessing = 0; 178 | }; 179 | /* End PBXResourcesBuildPhase section */ 180 | 181 | /* Begin PBXSourcesBuildPhase section */ 182 | 2AF54ED21A002CD1007A7144 /* Sources */ = { 183 | isa = PBXSourcesBuildPhase; 184 | buildActionMask = 2147483647; 185 | files = ( 186 | 2AF54F031A002D2B007A7144 /* RAReorderableLayout.swift in Sources */, 187 | 2A972DBE1A195D940084B0D5 /* VerticalViewController.swift in Sources */, 188 | 2AF54EE11A002CD1007A7144 /* ViewController.swift in Sources */, 189 | 2AF54EDC1A002CD1007A7144 /* AppDelegate.swift in Sources */, 190 | 2A972DC01A195F0C0084B0D5 /* HorizontalViewController.swift in Sources */, 191 | 2AF54EDF1A002CD1007A7144 /* RAReorderableLayout_Demo.xcdatamodeld in Sources */, 192 | ); 193 | runOnlyForDeploymentPostprocessing = 0; 194 | }; 195 | /* End PBXSourcesBuildPhase section */ 196 | 197 | /* Begin PBXVariantGroup section */ 198 | 2AF54EE71A002CD1007A7144 /* LaunchScreen.xib */ = { 199 | isa = PBXVariantGroup; 200 | children = ( 201 | 2AF54EE81A002CD1007A7144 /* Base */, 202 | ); 203 | name = LaunchScreen.xib; 204 | sourceTree = ""; 205 | }; 206 | /* End PBXVariantGroup section */ 207 | 208 | /* Begin XCBuildConfiguration section */ 209 | 2AF54EF61A002CD1007A7144 /* Debug */ = { 210 | isa = XCBuildConfiguration; 211 | buildSettings = { 212 | ALWAYS_SEARCH_USER_PATHS = NO; 213 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 214 | CLANG_CXX_LIBRARY = "libc++"; 215 | CLANG_ENABLE_MODULES = YES; 216 | CLANG_ENABLE_OBJC_ARC = YES; 217 | CLANG_WARN_BOOL_CONVERSION = YES; 218 | CLANG_WARN_CONSTANT_CONVERSION = YES; 219 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 220 | CLANG_WARN_EMPTY_BODY = YES; 221 | CLANG_WARN_ENUM_CONVERSION = YES; 222 | CLANG_WARN_INT_CONVERSION = YES; 223 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 224 | CLANG_WARN_UNREACHABLE_CODE = YES; 225 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 226 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 227 | COPY_PHASE_STRIP = NO; 228 | ENABLE_STRICT_OBJC_MSGSEND = YES; 229 | ENABLE_TESTABILITY = YES; 230 | GCC_C_LANGUAGE_STANDARD = gnu99; 231 | GCC_DYNAMIC_NO_PIC = NO; 232 | GCC_NO_COMMON_BLOCKS = YES; 233 | GCC_OPTIMIZATION_LEVEL = 0; 234 | GCC_PREPROCESSOR_DEFINITIONS = ( 235 | "DEBUG=1", 236 | "$(inherited)", 237 | ); 238 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 239 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 240 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 241 | GCC_WARN_UNDECLARED_SELECTOR = YES; 242 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 243 | GCC_WARN_UNUSED_FUNCTION = YES; 244 | GCC_WARN_UNUSED_VARIABLE = YES; 245 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 246 | MTL_ENABLE_DEBUG_INFO = YES; 247 | ONLY_ACTIVE_ARCH = YES; 248 | SDKROOT = iphoneos; 249 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 250 | }; 251 | name = Debug; 252 | }; 253 | 2AF54EF71A002CD1007A7144 /* Release */ = { 254 | isa = XCBuildConfiguration; 255 | buildSettings = { 256 | ALWAYS_SEARCH_USER_PATHS = NO; 257 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 258 | CLANG_CXX_LIBRARY = "libc++"; 259 | CLANG_ENABLE_MODULES = YES; 260 | CLANG_ENABLE_OBJC_ARC = YES; 261 | CLANG_WARN_BOOL_CONVERSION = YES; 262 | CLANG_WARN_CONSTANT_CONVERSION = YES; 263 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 264 | CLANG_WARN_EMPTY_BODY = YES; 265 | CLANG_WARN_ENUM_CONVERSION = YES; 266 | CLANG_WARN_INT_CONVERSION = YES; 267 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 268 | CLANG_WARN_UNREACHABLE_CODE = YES; 269 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 270 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 271 | COPY_PHASE_STRIP = YES; 272 | ENABLE_NS_ASSERTIONS = NO; 273 | ENABLE_STRICT_OBJC_MSGSEND = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu99; 275 | GCC_NO_COMMON_BLOCKS = YES; 276 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 277 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 278 | GCC_WARN_UNDECLARED_SELECTOR = YES; 279 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 280 | GCC_WARN_UNUSED_FUNCTION = YES; 281 | GCC_WARN_UNUSED_VARIABLE = YES; 282 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 283 | MTL_ENABLE_DEBUG_INFO = NO; 284 | SDKROOT = iphoneos; 285 | VALIDATE_PRODUCT = YES; 286 | }; 287 | name = Release; 288 | }; 289 | 2AF54EF91A002CD1007A7144 /* Debug */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 293 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 294 | FRAMEWORK_SEARCH_PATHS = ( 295 | "$(inherited)", 296 | "$(PROJECT_DIR)", 297 | ); 298 | INFOPLIST_FILE = "RAReorderableLayout-Demo/Info.plist"; 299 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 300 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 301 | LIBRARY_SEARCH_PATHS = ( 302 | "$(inherited)", 303 | "$(PROJECT_DIR)", 304 | ); 305 | PRODUCT_BUNDLE_IDENTIFIER = "com.ryo.$(PRODUCT_NAME:rfc1034identifier)"; 306 | PRODUCT_NAME = "$(TARGET_NAME)"; 307 | SWIFT_VERSION = 3.0; 308 | }; 309 | name = Debug; 310 | }; 311 | 2AF54EFA1A002CD1007A7144 /* Release */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 315 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 316 | FRAMEWORK_SEARCH_PATHS = ( 317 | "$(inherited)", 318 | "$(PROJECT_DIR)", 319 | ); 320 | INFOPLIST_FILE = "RAReorderableLayout-Demo/Info.plist"; 321 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 322 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 323 | LIBRARY_SEARCH_PATHS = ( 324 | "$(inherited)", 325 | "$(PROJECT_DIR)", 326 | ); 327 | PRODUCT_BUNDLE_IDENTIFIER = "com.ryo.$(PRODUCT_NAME:rfc1034identifier)"; 328 | PRODUCT_NAME = "$(TARGET_NAME)"; 329 | SWIFT_VERSION = 2.3; 330 | }; 331 | name = Release; 332 | }; 333 | /* End XCBuildConfiguration section */ 334 | 335 | /* Begin XCConfigurationList section */ 336 | 2AF54ED11A002CD1007A7144 /* Build configuration list for PBXProject "RAReorderableLayout-Demo" */ = { 337 | isa = XCConfigurationList; 338 | buildConfigurations = ( 339 | 2AF54EF61A002CD1007A7144 /* Debug */, 340 | 2AF54EF71A002CD1007A7144 /* Release */, 341 | ); 342 | defaultConfigurationIsVisible = 0; 343 | defaultConfigurationName = Release; 344 | }; 345 | 2AF54EF81A002CD1007A7144 /* Build configuration list for PBXNativeTarget "RAReorderableLayout-Demo" */ = { 346 | isa = XCConfigurationList; 347 | buildConfigurations = ( 348 | 2AF54EF91A002CD1007A7144 /* Debug */, 349 | 2AF54EFA1A002CD1007A7144 /* Release */, 350 | ); 351 | defaultConfigurationIsVisible = 0; 352 | defaultConfigurationName = Release; 353 | }; 354 | /* End XCConfigurationList section */ 355 | 356 | /* Begin XCVersionGroup section */ 357 | 2AF54EDD1A002CD1007A7144 /* RAReorderableLayout_Demo.xcdatamodeld */ = { 358 | isa = XCVersionGroup; 359 | children = ( 360 | 2AF54EDE1A002CD1007A7144 /* RAReorderableLayout_Demo.xcdatamodel */, 361 | ); 362 | currentVersion = 2AF54EDE1A002CD1007A7144 /* RAReorderableLayout_Demo.xcdatamodel */; 363 | path = RAReorderableLayout_Demo.xcdatamodeld; 364 | sourceTree = ""; 365 | versionGroupType = wrapper.xcdatamodel; 366 | }; 367 | /* End XCVersionGroup section */ 368 | }; 369 | rootObject = 2AF54ECE1A002CD1007A7144 /* Project object */; 370 | } 371 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // RAReorderableLayout-Demo 4 | // 5 | // Created by Ryo Aoyama on 10/29/14. 6 | // Copyright (c) 2014 Ryo Aoyama. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CoreData 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate { 14 | var window: UIWindow? 15 | } 16 | 17 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/HorizontalViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HorizontalViewController.swift 3 | // RAReorderableLayout-Demo 4 | // 5 | // Created by Ryo Aoyama on 11/17/14. 6 | // Copyright (c) 2014 Ryo Aoyama. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | class HorizontalViewController: UIViewController, RAReorderableLayoutDelegate, RAReorderableLayoutDataSource { 13 | @IBOutlet weak var collectionView: UICollectionView! 14 | @IBOutlet weak var gradientView: UIView! 15 | private var gradientLayer: CAGradientLayer? 16 | private var books: [Book] = [] 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | title = "RAReorderableLayout" 21 | collectionView.register(BookCell.self, forCellWithReuseIdentifier: "horizontalCell") 22 | collectionView.delegate = self 23 | collectionView.dataSource = self 24 | (collectionView.collectionViewLayout as! RAReorderableLayout).scrollDirection = .horizontal 25 | applyGradation() 26 | 27 | let aScalars = "A".unicodeScalars 28 | let zScalars = "Z".unicodeScalars 29 | let aAsciiCode = aScalars[aScalars.startIndex].value 30 | let zAsciiCode = zScalars[zScalars.startIndex].value 31 | books = (aAsciiCode...zAsciiCode) 32 | .flatMap(UnicodeScalar.init) 33 | .map(Character.init) 34 | .enumerated() 35 | .map { 36 | let title = "Book \(String($1))" 37 | let color = UIColor(hue: 255.0 / 26.0 * CGFloat($0) / 255.0, saturation: 1.0, brightness: 0.9, alpha: 1.0) 38 | return .init(title: title, color: color) 39 | } 40 | } 41 | 42 | override func viewDidLayoutSubviews() { 43 | super.viewDidLayoutSubviews() 44 | gradientLayer?.frame = gradientView.bounds 45 | } 46 | 47 | private func applyGradation() { 48 | gradientLayer = CAGradientLayer() 49 | gradientLayer!.frame = gradientView.bounds 50 | let mainColor = UIColor(white: 0, alpha: 0.3).cgColor 51 | let subColor = UIColor.clear.cgColor 52 | gradientLayer!.colors = [subColor, mainColor] 53 | gradientLayer!.locations = [0, 1] 54 | gradientView.layer.insertSublayer(gradientLayer!, at: 0) 55 | } 56 | 57 | // collectionView delegate datasource 58 | 59 | func numberOfSections(in collectionView: UICollectionView) -> Int { 60 | return 1 61 | } 62 | 63 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 64 | return books.count 65 | } 66 | 67 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 68 | return CGSize(width: 130.0, height: 170.0) 69 | } 70 | 71 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { 72 | return UIEdgeInsetsMake(0, 20.0, 0, 20.0) 73 | } 74 | 75 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 76 | return 20.0 77 | } 78 | 79 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 80 | var cell: BookCell 81 | cell = collectionView.dequeueReusableCell(withReuseIdentifier: "horizontalCell", for: indexPath) as! BookCell 82 | cell.book = books[(indexPath as NSIndexPath).item] 83 | return cell 84 | } 85 | 86 | func collectionView(_ collectionView: UICollectionView, at: IndexPath, willMoveTo toIndexPath: IndexPath) { 87 | 88 | } 89 | 90 | func collectionView(_ collectionView: UICollectionView, at: IndexPath, didMoveTo toIndexPath: IndexPath) { 91 | let book = books.remove(at: (toIndexPath as NSIndexPath).item) 92 | books.insert(book, at: (toIndexPath as NSIndexPath).item) 93 | } 94 | 95 | func scrollTrigerEdgeInsetsInCollectionView(_ collectionView: UICollectionView) -> UIEdgeInsets { 96 | return UIEdgeInsetsMake(0, 50, 0, 50) 97 | } 98 | 99 | func scrollSpeedValueInCollectionView(_ collectionView: UICollectionView) -> CGFloat { 100 | return 15.0 101 | } 102 | } 103 | 104 | class BookCell: UICollectionViewCell { 105 | private var backCoverView: UIView! 106 | private var pagesView: UIView! 107 | private var frontCoverView: UIView! 108 | private var bindingView: UIView! 109 | private var titleLabel: UILabel! 110 | var book: Book? { 111 | didSet { 112 | titleLabel.text = book?.title 113 | color = book?.color 114 | } 115 | } 116 | var color: UIColor? { 117 | didSet { 118 | backCoverView.backgroundColor = getDarkColor(color, minusValue: 20.0) 119 | frontCoverView.backgroundColor = color 120 | bindingView.backgroundColor = getDarkColor(color, minusValue: 50.0) 121 | } 122 | } 123 | 124 | required init?(coder aDecoder: NSCoder) { 125 | super.init(coder: aDecoder) 126 | } 127 | 128 | override init(frame: CGRect) { 129 | super.init(frame: frame) 130 | configure() 131 | } 132 | 133 | override func prepareForReuse() { 134 | super.prepareForReuse() 135 | titleLabel.text = nil 136 | } 137 | 138 | private func configure() { 139 | backCoverView = UIView(frame: bounds) 140 | backCoverView.backgroundColor = getDarkColor(UIColor.red, minusValue: 20.0) 141 | backCoverView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 142 | 143 | pagesView = UIView(frame: CGRect(x: 15.0, y: 0, width: bounds.width - 25.0, height: bounds.height - 5.0)) 144 | pagesView.backgroundColor = UIColor.white 145 | pagesView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 146 | 147 | frontCoverView = UIView(frame: CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height - 10.0)) 148 | frontCoverView.backgroundColor = UIColor.red 149 | frontCoverView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 150 | 151 | bindingView = UIView(frame: CGRect(x: 0, y: 0, width: 15.0, height: bounds.height)) 152 | bindingView.backgroundColor = getDarkColor(backCoverView?.backgroundColor, minusValue: 50.0) 153 | bindingView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 154 | bindingView.layer.borderWidth = 1.0 155 | bindingView.layer.borderColor = UIColor.black.cgColor 156 | 157 | titleLabel = UILabel(frame: CGRect(x: 15.0, y: 30.0, width: bounds.width - 16.0, height: 30.0)) 158 | titleLabel.backgroundColor = UIColor(white: 1.0, alpha: 0.8) 159 | titleLabel.textColor = UIColor.black 160 | titleLabel.textAlignment = .center 161 | titleLabel.font = UIFont.boldSystemFont(ofSize: 20.0) 162 | 163 | contentView.addSubview(backCoverView) 164 | contentView.addSubview(pagesView) 165 | contentView.addSubview(frontCoverView) 166 | contentView.addSubview(bindingView) 167 | contentView.addSubview(titleLabel) 168 | 169 | let backPath = UIBezierPath(roundedRect: backCoverView!.bounds, byRoundingCorners: [.topRight, .bottomRight], cornerRadii: CGSize(width: 10.0, height: 10.0)) 170 | let backMask = CAShapeLayer() 171 | backMask.frame = backCoverView!.bounds 172 | backMask.path = backPath.cgPath 173 | let backLineLayer = CAShapeLayer() 174 | backLineLayer.frame = backCoverView!.bounds 175 | backLineLayer.path = backPath.cgPath 176 | backLineLayer.strokeColor = UIColor.black.cgColor 177 | backLineLayer.fillColor = UIColor.clear.cgColor 178 | backLineLayer.lineWidth = 2.0 179 | backCoverView!.layer.mask = backMask 180 | backCoverView!.layer.insertSublayer(backLineLayer, at: 0) 181 | 182 | let frontPath = UIBezierPath(roundedRect: frontCoverView!.bounds, byRoundingCorners: [.topRight, .bottomRight], cornerRadii: CGSize(width: 10.0, height: 10.0)) 183 | let frontMask = CAShapeLayer() 184 | frontMask.frame = frontCoverView!.bounds 185 | frontMask.path = frontPath.cgPath 186 | let frontLineLayer = CAShapeLayer() 187 | frontLineLayer.path = frontPath.cgPath 188 | frontLineLayer.strokeColor = UIColor.black.cgColor 189 | frontLineLayer.fillColor = UIColor.clear.cgColor 190 | frontLineLayer.lineWidth = 2.0 191 | frontCoverView!.layer.mask = frontMask 192 | frontCoverView!.layer.insertSublayer(frontLineLayer, at: 0) 193 | } 194 | 195 | private func getDarkColor(_ color: UIColor?, minusValue: CGFloat) -> UIColor? { 196 | if color == nil { 197 | return nil 198 | } 199 | var r: CGFloat = 0 200 | var g: CGFloat = 0 201 | var b: CGFloat = 0 202 | var a: CGFloat = 0 203 | color!.getRed(&r, green: &g, blue: &b, alpha: &a) 204 | r -= max(minusValue / 255.0, 0) 205 | g -= max(minusValue / 255.0, 0) 206 | b -= max(minusValue / 255.0, 0) 207 | return UIColor(red: r, green: g, blue: b, alpha: a) 208 | } 209 | } 210 | 211 | class Book: NSObject { 212 | var title: String? 213 | var color: UIColor? 214 | 215 | init(title: String?, color: UIColor) { 216 | super.init() 217 | self.title = title 218 | self.color = color 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.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" : "1x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "29x29", 26 | "scale" : "3x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "40x40", 36 | "scale" : "3x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "57x57", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "iphone", 45 | "size" : "57x57", 46 | "scale" : "2x" 47 | }, 48 | { 49 | "idiom" : "iphone", 50 | "size" : "60x60", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "iphone", 55 | "size" : "60x60", 56 | "scale" : "3x" 57 | } 58 | ], 59 | "info" : { 60 | "version" : 1, 61 | "author" : "xcode" 62 | } 63 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "8.0", 8 | "subtype" : "736h", 9 | "scale" : "3x" 10 | }, 11 | { 12 | "orientation" : "landscape", 13 | "idiom" : "iphone", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "8.0", 16 | "subtype" : "736h", 17 | "scale" : "3x" 18 | }, 19 | { 20 | "orientation" : "portrait", 21 | "idiom" : "iphone", 22 | "extent" : "full-screen", 23 | "minimum-system-version" : "8.0", 24 | "subtype" : "667h", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "orientation" : "portrait", 29 | "idiom" : "iphone", 30 | "extent" : "full-screen", 31 | "minimum-system-version" : "7.0", 32 | "scale" : "2x" 33 | }, 34 | { 35 | "orientation" : "portrait", 36 | "idiom" : "iphone", 37 | "extent" : "full-screen", 38 | "minimum-system-version" : "7.0", 39 | "subtype" : "retina4", 40 | "scale" : "2x" 41 | }, 42 | { 43 | "orientation" : "portrait", 44 | "idiom" : "iphone", 45 | "extent" : "full-screen", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "orientation" : "portrait", 50 | "idiom" : "iphone", 51 | "extent" : "full-screen", 52 | "scale" : "2x" 53 | }, 54 | { 55 | "orientation" : "portrait", 56 | "idiom" : "iphone", 57 | "extent" : "full-screen", 58 | "subtype" : "retina4", 59 | "scale" : "2x" 60 | } 61 | ], 62 | "info" : { 63 | "version" : 1, 64 | "author" : "xcode" 65 | } 66 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample0.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample0.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample0.imageset/Sample0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample0.imageset/Sample0.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample1.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample1.imageset/Sample1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample1.imageset/Sample1.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample10.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample10.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample10.imageset/Sample10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample10.imageset/Sample10.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample11.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample11.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample11.imageset/Sample11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample11.imageset/Sample11.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample12.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample12.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample12.imageset/Sample12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample12.imageset/Sample12.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample13.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample13.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample13.imageset/Sample13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample13.imageset/Sample13.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample14.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample14.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample14.imageset/Sample14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample14.imageset/Sample14.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample15.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample15.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample15.imageset/Sample15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample15.imageset/Sample15.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample16.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample16.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample16.imageset/Sample16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample16.imageset/Sample16.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample17.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample17.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample17.imageset/Sample17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample17.imageset/Sample17.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample18.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample18.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample18.imageset/Sample18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample18.imageset/Sample18.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample19.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample19.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample19.imageset/Sample19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample19.imageset/Sample19.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample2.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample2.imageset/Sample2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample2.imageset/Sample2.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample20.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample20.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample20.imageset/Sample20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample20.imageset/Sample20.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample21.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample21.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample21.imageset/Sample21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample21.imageset/Sample21.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample22.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample22.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample22.imageset/Sample22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample22.imageset/Sample22.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample23.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample23.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample23.imageset/Sample23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample23.imageset/Sample23.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample24.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample24.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample24.imageset/Sample24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample24.imageset/Sample24.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample25.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample25.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample25.imageset/Sample25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample25.imageset/Sample25.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample26.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample26.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample26.imageset/Sample26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample26.imageset/Sample26.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample27.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample27.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample27.imageset/Sample27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample27.imageset/Sample27.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample28.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample28.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample28.imageset/Sample28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample28.imageset/Sample28.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample29.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample29.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample29.imageset/Sample29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample29.imageset/Sample29.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample3.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample3.imageset/Sample3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample3.imageset/Sample3.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample4.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample4.imageset/Sample4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample4.imageset/Sample4.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample5.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample5.imageset/Sample5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample5.imageset/Sample5.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample6.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample6.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample6.imageset/Sample6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample6.imageset/Sample6.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample7.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample7.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample7.imageset/Sample7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample7.imageset/Sample7.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample8.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample8.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample8.imageset/Sample8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample8.imageset/Sample8.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample9.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Sample9.jpg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample9.imageset/Sample9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ra1028/RAReorderableLayout/b68e5a5eedaaae93e9ae60b7d394bf45d43443d6/RAReorderableLayout-Demo/RAReorderableLayout-Demo/Images.xcassets/sample/Sample9.imageset/Sample9.jpg -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIcons 10 | 11 | CFBundleIcons~ipad 12 | 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1 27 | LSRequiresIPhoneOS 28 | 29 | UILaunchStoryboardName 30 | Main 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/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 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/RAReorderableLayout_Demo.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | RAReorderableLayout_Demo.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/RAReorderableLayout_Demo.xcdatamodeld/RAReorderableLayout_Demo.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/VerticalViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VerticalViewController.swift 3 | // RAReorderableLayout-Demo 4 | // 5 | // Created by Ryo Aoyama on 11/17/14. 6 | // Copyright (c) 2014 Ryo Aoyama. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class VerticalViewController: UIViewController, RAReorderableLayoutDelegate, RAReorderableLayoutDataSource { 12 | 13 | @IBOutlet var collectionView: UICollectionView! 14 | 15 | var imagesForSection0: [UIImage] = [] 16 | var imagesForSection1: [UIImage] = [] 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | self.title = "RAReorderableLayout" 21 | let nib = UINib(nibName: "verticalCell", bundle: nil) 22 | collectionView.register(nib, forCellWithReuseIdentifier: "cell") 23 | collectionView.delegate = self 24 | collectionView.dataSource = self 25 | 26 | for index in 0..<18 { 27 | let name = "Sample\(index).jpg" 28 | let image = UIImage(named: name) 29 | imagesForSection0.append(image!) 30 | } 31 | for index in 18..<30 { 32 | let name = "Sample\(index).jpg" 33 | let image = UIImage(named: name) 34 | imagesForSection1.append(image!) 35 | } 36 | } 37 | 38 | override func viewDidLayoutSubviews() { 39 | super.viewDidLayoutSubviews() 40 | collectionView.contentInset = UIEdgeInsetsMake(topLayoutGuide.length, 0, 0, 0) 41 | } 42 | 43 | // RAReorderableLayout delegate datasource 44 | 45 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 46 | let screenWidth = UIScreen.main.bounds.width 47 | let threePiecesWidth = floor(screenWidth / 3.0 - ((2.0 / 3) * 2)) 48 | let twoPiecesWidth = floor(screenWidth / 2.0 - (2.0 / 2)) 49 | if (indexPath as NSIndexPath).section == 0 { 50 | return CGSize(width: threePiecesWidth, height: threePiecesWidth) 51 | }else { 52 | return CGSize(width: twoPiecesWidth, height: twoPiecesWidth) 53 | } 54 | } 55 | 56 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { 57 | return 2.0 58 | } 59 | 60 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 61 | return 2.0 62 | } 63 | 64 | func numberOfSections(in collectionView: UICollectionView) -> Int { 65 | return 2 66 | } 67 | 68 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { 69 | return UIEdgeInsetsMake(0, 0, 2.0, 0) 70 | } 71 | 72 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 73 | if section == 0 { 74 | return imagesForSection0.count 75 | }else { 76 | return imagesForSection1.count 77 | } 78 | } 79 | 80 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 81 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "verticalCell", for: indexPath) as! RACollectionViewCell 82 | 83 | if (indexPath as NSIndexPath).section == 0 { 84 | cell.imageView.image = imagesForSection0[(indexPath as NSIndexPath).item] 85 | }else { 86 | cell.imageView.image = imagesForSection1[(indexPath as NSIndexPath).item] 87 | } 88 | return cell 89 | } 90 | 91 | func collectionView(_ collectionView: UICollectionView, allowMoveAt indexPath: IndexPath) -> Bool { 92 | if collectionView.numberOfItems(inSection: (indexPath as NSIndexPath).section) <= 1 { 93 | return false 94 | } 95 | return true 96 | } 97 | 98 | func collectionView(_ collectionView: UICollectionView, at: IndexPath, willMoveTo toIndexPath: IndexPath) { 99 | 100 | } 101 | 102 | func collectionView(_ collectionView: UICollectionView, at atIndexPath: IndexPath, didMoveTo toIndexPath: IndexPath) { 103 | var photo: UIImage 104 | if (atIndexPath as NSIndexPath).section == 0 { 105 | photo = imagesForSection0.remove(at: (atIndexPath as NSIndexPath).item) 106 | }else { 107 | photo = imagesForSection1.remove(at: (atIndexPath as NSIndexPath).item) 108 | } 109 | 110 | if (toIndexPath as NSIndexPath).section == 0 { 111 | imagesForSection0.insert(photo, at: (toIndexPath as NSIndexPath).item) 112 | }else { 113 | imagesForSection1.insert(photo, at: (toIndexPath as NSIndexPath).item) 114 | } 115 | } 116 | 117 | func scrollTrigerEdgeInsetsInCollectionView(_ collectionView: UICollectionView) -> UIEdgeInsets { 118 | return UIEdgeInsetsMake(100.0, 100.0, 100.0, 100.0) 119 | } 120 | 121 | func collectionView(_ collectionView: UICollectionView, reorderingItemAlphaInSection section: Int) -> CGFloat { 122 | if section == 0 { 123 | return 0 124 | }else { 125 | return 0.3 126 | } 127 | } 128 | 129 | func scrollTrigerPaddingInCollectionView(_ collectionView: UICollectionView) -> UIEdgeInsets { 130 | return UIEdgeInsetsMake(collectionView.contentInset.top, 0, collectionView.contentInset.bottom, 0) 131 | } 132 | } 133 | 134 | class RACollectionViewCell: UICollectionViewCell { 135 | var imageView: UIImageView! 136 | var gradientLayer: CAGradientLayer? 137 | var hilightedCover: UIView! 138 | override var isHighlighted: Bool { 139 | didSet { 140 | hilightedCover.isHidden = !isHighlighted 141 | } 142 | } 143 | 144 | required init?(coder aDecoder: NSCoder) { 145 | super.init(coder: aDecoder) 146 | configure() 147 | } 148 | 149 | override func layoutSubviews() { 150 | super.layoutSubviews() 151 | imageView.frame = bounds 152 | hilightedCover.frame = bounds 153 | applyGradation(imageView) 154 | } 155 | 156 | private func configure() { 157 | imageView = UIImageView() 158 | imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 159 | imageView.contentMode = UIViewContentMode.scaleAspectFill 160 | addSubview(imageView) 161 | 162 | hilightedCover = UIView() 163 | hilightedCover.autoresizingMask = [.flexibleWidth, .flexibleHeight] 164 | hilightedCover.backgroundColor = UIColor(white: 0, alpha: 0.5) 165 | hilightedCover.isHidden = true 166 | addSubview(hilightedCover) 167 | } 168 | 169 | private func applyGradation(_ gradientView: UIView!) { 170 | gradientLayer?.removeFromSuperlayer() 171 | gradientLayer = nil 172 | 173 | gradientLayer = CAGradientLayer() 174 | gradientLayer!.frame = gradientView.bounds 175 | 176 | let mainColor = UIColor(white: 0, alpha: 0.3).cgColor 177 | let subColor = UIColor.clear.cgColor 178 | gradientLayer!.colors = [subColor, mainColor] 179 | gradientLayer!.locations = [0, 1] 180 | 181 | gradientView.layer.addSublayer(gradientLayer!) 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-Demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // RAReorderableLayout-Demo 4 | // 5 | // Created by Ryo Aoyama on 10/29/14. 6 | // Copyright (c) 2014 Ryo Aoyama. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | @IBOutlet weak var verticalButton: RAButton! 13 | 14 | @IBOutlet weak var horizontalButton: RAButton! 15 | 16 | required init?(coder aDecoder: NSCoder) { 17 | super.init(coder: aDecoder) 18 | } 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | title = "RAReorderableLayout" 23 | verticalButton.isExclusiveTouch = true 24 | horizontalButton.isExclusiveTouch = true 25 | } 26 | 27 | override func viewWillAppear(_ animated: Bool) { 28 | super.viewWillAppear(animated) 29 | let num1: CGFloat = CGFloat(arc4random_uniform(256)) / 255.0 30 | let num2: CGFloat = CGFloat(arc4random_uniform(256)) / 255.0 31 | let num3: CGFloat = CGFloat(arc4random_uniform(256)) / 255.0 32 | let color1: UIColor = UIColor(red: num1, green: num2, blue: num3, alpha: 1.0) 33 | let color2: UIColor = UIColor(red: num3, green: num2, blue: num1, alpha: 1.0) 34 | 35 | if (num1 + num2 + num3) / 3.0 >= 0.5 { 36 | verticalButton.setTitleColor(UIColor.black, for: UIControlState()) 37 | horizontalButton.setTitleColor(UIColor.black, for: UIControlState()) 38 | }else { 39 | verticalButton.setTitleColor(UIColor.white, for: UIControlState()) 40 | horizontalButton.setTitleColor(UIColor.white, for: UIControlState()) 41 | } 42 | 43 | verticalButton.backgroundColor = color1 44 | horizontalButton.backgroundColor = color2 45 | } 46 | } 47 | 48 | class RAButton: UIButton { 49 | var baseView: UIView! 50 | 51 | override var isHighlighted: Bool { 52 | didSet { 53 | let transform: CGAffineTransform = isHighlighted ? 54 | CGAffineTransform(scaleX: 1.1, y: 1.1) : CGAffineTransform.identity 55 | UIView.animate( 56 | withDuration: 0.05, 57 | delay: 0, 58 | options: .beginFromCurrentState, 59 | animations: { 60 | self.transform = transform 61 | }, 62 | completion: nil 63 | ) 64 | } 65 | } 66 | 67 | required init?(coder aDecoder: NSCoder) { 68 | super.init(coder: aDecoder) 69 | configure() 70 | } 71 | 72 | override func layoutSubviews() { 73 | super.layoutSubviews() 74 | layer.cornerRadius = bounds.width / 2; 75 | } 76 | 77 | private func configure() { 78 | baseView = UIView(frame: bounds) 79 | layer.cornerRadius = bounds.width 80 | baseView.addSubview(self) 81 | translatesAutoresizingMaskIntoConstraints = false 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-DemoTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /RAReorderableLayout-Demo/RAReorderableLayout-DemoTests/RAReorderableLayout_DemoTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RAReorderableLayout_DemoTests.swift 3 | // RAReorderableLayout-DemoTests 4 | // 5 | // Created by Ryo Aoyama on 10/29/14. 6 | // Copyright (c) 2014 Ryo Aoyama. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class RAReorderableLayout_DemoTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /RAReorderableLayout.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "RAReorderableLayout" 3 | s.version = "0.6.1" 4 | s.summary = "A UICollectionView layout which you can move items with drag and drop." 5 | s.license = { :type => 'MIT', :file => 'LICENSE' } 6 | s.homepage = "https://github.com/ra1028" 7 | s.author = { "ra1028" => "r.fe51028.r@gmail.com" } 8 | s.platform = :ios, '8.0' 9 | s.source = { :git => "https://github.com/ra1028/RAReorderableLayout.git", :tag => s.version.to_s } 10 | s.requires_arc = true 11 | s.source_files = 'RAReorderableLayout/*.swift' 12 | end 13 | -------------------------------------------------------------------------------- /RAReorderableLayout.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DFF5E7531B8F05CE003726B0 /* RAReorderableLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = DFF5E7521B8F05CE003726B0 /* RAReorderableLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | DFF5E75B1B8F061B003726B0 /* RAReorderableLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF5E75A1B8F061B003726B0 /* RAReorderableLayout.swift */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXFileReference section */ 15 | DFF5E74F1B8F05CE003726B0 /* RAReorderableLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RAReorderableLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 16 | DFF5E7521B8F05CE003726B0 /* RAReorderableLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RAReorderableLayout.h; sourceTree = ""; }; 17 | DFF5E7541B8F05CE003726B0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 18 | DFF5E75A1B8F061B003726B0 /* RAReorderableLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RAReorderableLayout.swift; sourceTree = ""; }; 19 | /* End PBXFileReference section */ 20 | 21 | /* Begin PBXFrameworksBuildPhase section */ 22 | DFF5E74B1B8F05CE003726B0 /* Frameworks */ = { 23 | isa = PBXFrameworksBuildPhase; 24 | buildActionMask = 2147483647; 25 | files = ( 26 | ); 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXFrameworksBuildPhase section */ 30 | 31 | /* Begin PBXGroup section */ 32 | DFF5E7451B8F05CE003726B0 = { 33 | isa = PBXGroup; 34 | children = ( 35 | DFF5E7511B8F05CE003726B0 /* RAReorderableLayout */, 36 | DFF5E7501B8F05CE003726B0 /* Products */, 37 | ); 38 | sourceTree = ""; 39 | }; 40 | DFF5E7501B8F05CE003726B0 /* Products */ = { 41 | isa = PBXGroup; 42 | children = ( 43 | DFF5E74F1B8F05CE003726B0 /* RAReorderableLayout.framework */, 44 | ); 45 | name = Products; 46 | sourceTree = ""; 47 | }; 48 | DFF5E7511B8F05CE003726B0 /* RAReorderableLayout */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | DFF5E7521B8F05CE003726B0 /* RAReorderableLayout.h */, 52 | DFF5E75A1B8F061B003726B0 /* RAReorderableLayout.swift */, 53 | DFF5E7541B8F05CE003726B0 /* Info.plist */, 54 | ); 55 | path = RAReorderableLayout; 56 | sourceTree = ""; 57 | }; 58 | /* End PBXGroup section */ 59 | 60 | /* Begin PBXHeadersBuildPhase section */ 61 | DFF5E74C1B8F05CE003726B0 /* Headers */ = { 62 | isa = PBXHeadersBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | DFF5E7531B8F05CE003726B0 /* RAReorderableLayout.h in Headers */, 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | /* End PBXHeadersBuildPhase section */ 70 | 71 | /* Begin PBXNativeTarget section */ 72 | DFF5E74E1B8F05CE003726B0 /* RAReorderableLayout */ = { 73 | isa = PBXNativeTarget; 74 | buildConfigurationList = DFF5E7571B8F05CE003726B0 /* Build configuration list for PBXNativeTarget "RAReorderableLayout" */; 75 | buildPhases = ( 76 | DFF5E74A1B8F05CE003726B0 /* Sources */, 77 | DFF5E74B1B8F05CE003726B0 /* Frameworks */, 78 | DFF5E74C1B8F05CE003726B0 /* Headers */, 79 | DFF5E74D1B8F05CE003726B0 /* Resources */, 80 | ); 81 | buildRules = ( 82 | ); 83 | dependencies = ( 84 | ); 85 | name = RAReorderableLayout; 86 | productName = RAReorderableLayout; 87 | productReference = DFF5E74F1B8F05CE003726B0 /* RAReorderableLayout.framework */; 88 | productType = "com.apple.product-type.framework"; 89 | }; 90 | /* End PBXNativeTarget section */ 91 | 92 | /* Begin PBXProject section */ 93 | DFF5E7461B8F05CE003726B0 /* Project object */ = { 94 | isa = PBXProject; 95 | attributes = { 96 | LastSwiftUpdateCheck = 0700; 97 | LastUpgradeCheck = 0800; 98 | ORGANIZATIONNAME = "Yowoo Technology Inc."; 99 | TargetAttributes = { 100 | DFF5E74E1B8F05CE003726B0 = { 101 | CreatedOnToolsVersion = 7.0; 102 | LastSwiftMigration = 0800; 103 | }; 104 | }; 105 | }; 106 | buildConfigurationList = DFF5E7491B8F05CE003726B0 /* Build configuration list for PBXProject "RAReorderableLayout" */; 107 | compatibilityVersion = "Xcode 3.2"; 108 | developmentRegion = English; 109 | hasScannedForEncodings = 0; 110 | knownRegions = ( 111 | en, 112 | ); 113 | mainGroup = DFF5E7451B8F05CE003726B0; 114 | productRefGroup = DFF5E7501B8F05CE003726B0 /* Products */; 115 | projectDirPath = ""; 116 | projectRoot = ""; 117 | targets = ( 118 | DFF5E74E1B8F05CE003726B0 /* RAReorderableLayout */, 119 | ); 120 | }; 121 | /* End PBXProject section */ 122 | 123 | /* Begin PBXResourcesBuildPhase section */ 124 | DFF5E74D1B8F05CE003726B0 /* Resources */ = { 125 | isa = PBXResourcesBuildPhase; 126 | buildActionMask = 2147483647; 127 | files = ( 128 | ); 129 | runOnlyForDeploymentPostprocessing = 0; 130 | }; 131 | /* End PBXResourcesBuildPhase section */ 132 | 133 | /* Begin PBXSourcesBuildPhase section */ 134 | DFF5E74A1B8F05CE003726B0 /* Sources */ = { 135 | isa = PBXSourcesBuildPhase; 136 | buildActionMask = 2147483647; 137 | files = ( 138 | DFF5E75B1B8F061B003726B0 /* RAReorderableLayout.swift in Sources */, 139 | ); 140 | runOnlyForDeploymentPostprocessing = 0; 141 | }; 142 | /* End PBXSourcesBuildPhase section */ 143 | 144 | /* Begin XCBuildConfiguration section */ 145 | DFF5E7551B8F05CE003726B0 /* Debug */ = { 146 | isa = XCBuildConfiguration; 147 | buildSettings = { 148 | ALWAYS_SEARCH_USER_PATHS = NO; 149 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 150 | CLANG_CXX_LIBRARY = "libc++"; 151 | CLANG_ENABLE_MODULES = YES; 152 | CLANG_ENABLE_OBJC_ARC = YES; 153 | CLANG_WARN_BOOL_CONVERSION = YES; 154 | CLANG_WARN_CONSTANT_CONVERSION = YES; 155 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 156 | CLANG_WARN_EMPTY_BODY = YES; 157 | CLANG_WARN_ENUM_CONVERSION = YES; 158 | CLANG_WARN_INT_CONVERSION = YES; 159 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 160 | CLANG_WARN_UNREACHABLE_CODE = YES; 161 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 162 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 163 | COPY_PHASE_STRIP = NO; 164 | CURRENT_PROJECT_VERSION = 1; 165 | DEBUG_INFORMATION_FORMAT = dwarf; 166 | ENABLE_STRICT_OBJC_MSGSEND = YES; 167 | ENABLE_TESTABILITY = YES; 168 | GCC_C_LANGUAGE_STANDARD = gnu99; 169 | GCC_DYNAMIC_NO_PIC = NO; 170 | GCC_NO_COMMON_BLOCKS = YES; 171 | GCC_OPTIMIZATION_LEVEL = 0; 172 | GCC_PREPROCESSOR_DEFINITIONS = ( 173 | "DEBUG=1", 174 | "$(inherited)", 175 | ); 176 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 177 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 178 | GCC_WARN_UNDECLARED_SELECTOR = YES; 179 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 180 | GCC_WARN_UNUSED_FUNCTION = YES; 181 | GCC_WARN_UNUSED_VARIABLE = YES; 182 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 183 | MTL_ENABLE_DEBUG_INFO = YES; 184 | ONLY_ACTIVE_ARCH = YES; 185 | SDKROOT = iphoneos; 186 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 187 | TARGETED_DEVICE_FAMILY = "1,2"; 188 | VERSIONING_SYSTEM = "apple-generic"; 189 | VERSION_INFO_PREFIX = ""; 190 | }; 191 | name = Debug; 192 | }; 193 | DFF5E7561B8F05CE003726B0 /* Release */ = { 194 | isa = XCBuildConfiguration; 195 | buildSettings = { 196 | ALWAYS_SEARCH_USER_PATHS = NO; 197 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 198 | CLANG_CXX_LIBRARY = "libc++"; 199 | CLANG_ENABLE_MODULES = YES; 200 | CLANG_ENABLE_OBJC_ARC = YES; 201 | CLANG_WARN_BOOL_CONVERSION = YES; 202 | CLANG_WARN_CONSTANT_CONVERSION = YES; 203 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 204 | CLANG_WARN_EMPTY_BODY = YES; 205 | CLANG_WARN_ENUM_CONVERSION = YES; 206 | CLANG_WARN_INT_CONVERSION = YES; 207 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 208 | CLANG_WARN_UNREACHABLE_CODE = YES; 209 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 210 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 211 | COPY_PHASE_STRIP = NO; 212 | CURRENT_PROJECT_VERSION = 1; 213 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 214 | ENABLE_NS_ASSERTIONS = NO; 215 | ENABLE_STRICT_OBJC_MSGSEND = YES; 216 | GCC_C_LANGUAGE_STANDARD = gnu99; 217 | GCC_NO_COMMON_BLOCKS = YES; 218 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 219 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 220 | GCC_WARN_UNDECLARED_SELECTOR = YES; 221 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 222 | GCC_WARN_UNUSED_FUNCTION = YES; 223 | GCC_WARN_UNUSED_VARIABLE = YES; 224 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 225 | MTL_ENABLE_DEBUG_INFO = NO; 226 | SDKROOT = iphoneos; 227 | TARGETED_DEVICE_FAMILY = "1,2"; 228 | VALIDATE_PRODUCT = YES; 229 | VERSIONING_SYSTEM = "apple-generic"; 230 | VERSION_INFO_PREFIX = ""; 231 | }; 232 | name = Release; 233 | }; 234 | DFF5E7581B8F05CE003726B0 /* Debug */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | CLANG_ENABLE_MODULES = YES; 238 | DEFINES_MODULE = YES; 239 | DYLIB_COMPATIBILITY_VERSION = 1; 240 | DYLIB_CURRENT_VERSION = 1; 241 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 242 | INFOPLIST_FILE = RAReorderableLayout/Info.plist; 243 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 244 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 245 | PRODUCT_BUNDLE_IDENTIFIER = "com.yo-woo.RAReorderableLayout"; 246 | PRODUCT_NAME = "$(TARGET_NAME)"; 247 | SKIP_INSTALL = YES; 248 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 249 | SWIFT_VERSION = 3.0; 250 | }; 251 | name = Debug; 252 | }; 253 | DFF5E7591B8F05CE003726B0 /* Release */ = { 254 | isa = XCBuildConfiguration; 255 | buildSettings = { 256 | CLANG_ENABLE_MODULES = YES; 257 | DEFINES_MODULE = YES; 258 | DYLIB_COMPATIBILITY_VERSION = 1; 259 | DYLIB_CURRENT_VERSION = 1; 260 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 261 | INFOPLIST_FILE = RAReorderableLayout/Info.plist; 262 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 263 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 264 | PRODUCT_BUNDLE_IDENTIFIER = "com.yo-woo.RAReorderableLayout"; 265 | PRODUCT_NAME = "$(TARGET_NAME)"; 266 | SKIP_INSTALL = YES; 267 | SWIFT_VERSION = 3.0; 268 | }; 269 | name = Release; 270 | }; 271 | /* End XCBuildConfiguration section */ 272 | 273 | /* Begin XCConfigurationList section */ 274 | DFF5E7491B8F05CE003726B0 /* Build configuration list for PBXProject "RAReorderableLayout" */ = { 275 | isa = XCConfigurationList; 276 | buildConfigurations = ( 277 | DFF5E7551B8F05CE003726B0 /* Debug */, 278 | DFF5E7561B8F05CE003726B0 /* Release */, 279 | ); 280 | defaultConfigurationIsVisible = 0; 281 | defaultConfigurationName = Release; 282 | }; 283 | DFF5E7571B8F05CE003726B0 /* Build configuration list for PBXNativeTarget "RAReorderableLayout" */ = { 284 | isa = XCConfigurationList; 285 | buildConfigurations = ( 286 | DFF5E7581B8F05CE003726B0 /* Debug */, 287 | DFF5E7591B8F05CE003726B0 /* Release */, 288 | ); 289 | defaultConfigurationIsVisible = 0; 290 | defaultConfigurationName = Release; 291 | }; 292 | /* End XCConfigurationList section */ 293 | }; 294 | rootObject = DFF5E7461B8F05CE003726B0 /* Project object */; 295 | } 296 | -------------------------------------------------------------------------------- /RAReorderableLayout.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RAReorderableLayout.xcodeproj/xcshareddata/xcschemes/RAReorderableLayout.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /RAReorderableLayout/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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /RAReorderableLayout/RAReorderableLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // RAReorderableLayout.h 3 | // RAReorderableLayout 4 | // 5 | // Created by Yimin Lin on 8/27/15. 6 | // Copyright © 2015 Yowoo Technology Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for RAReorderableLayout. 12 | FOUNDATION_EXPORT double RAReorderableLayoutVersionNumber; 13 | 14 | //! Project version string for RAReorderableLayout. 15 | FOUNDATION_EXPORT const unsigned char RAReorderableLayoutVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /RAReorderableLayout/RAReorderableLayout.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RAReorderableLayout.swift 3 | // RAReorderableLayout 4 | // 5 | // Created by Ryo Aoyama on 10/12/14. 6 | // Copyright (c) 2014 Ryo Aoyama. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol RAReorderableLayoutDelegate: UICollectionViewDelegateFlowLayout { 12 | func collectionView(_ collectionView: UICollectionView, at: IndexPath, willMoveTo toIndexPath: IndexPath) 13 | func collectionView(_ collectionView: UICollectionView, at: IndexPath, didMoveTo toIndexPath: IndexPath) 14 | func collectionView(_ collectionView: UICollectionView, allowMoveAt indexPath: IndexPath) -> Bool 15 | func collectionView(_ collectionView: UICollectionView, at: IndexPath, canMoveTo: IndexPath) -> Bool 16 | 17 | func collectionView(_ collectionView: UICollectionView, collectionView layout: RAReorderableLayout, willBeginDraggingItemAt indexPath: IndexPath) 18 | func collectionView(_ collectionView: UICollectionView, collectionView layout: RAReorderableLayout, didBeginDraggingItemAt indexPath: IndexPath) 19 | func collectionView(_ collectionView: UICollectionView, collectionView layout: RAReorderableLayout, willEndDraggingItemTo indexPath: IndexPath) 20 | func collectionView(_ collectionView: UICollectionView, collectionView layout: RAReorderableLayout, didEndDraggingItemTo indexPath: IndexPath) 21 | } 22 | 23 | public protocol RAReorderableLayoutDataSource: UICollectionViewDataSource { 24 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 25 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 26 | 27 | func collectionView(_ collectionView: UICollectionView, reorderingItemAlphaInSection section: Int) -> CGFloat 28 | func scrollTrigerEdgeInsetsInCollectionView(_ collectionView: UICollectionView) -> UIEdgeInsets 29 | func scrollTrigerPaddingInCollectionView(_ collectionView: UICollectionView) -> UIEdgeInsets 30 | func scrollSpeedValueInCollectionView(_ collectionView: UICollectionView) -> CGFloat 31 | } 32 | 33 | public extension RAReorderableLayoutDataSource { 34 | func collectionView(_ collectionView: UICollectionView, reorderingItemAlphaInSection section: Int) -> CGFloat { 35 | return 0 36 | } 37 | func scrollTrigerEdgeInsetsInCollectionView(_ collectionView: UICollectionView) -> UIEdgeInsets { 38 | return .init(top: 100, left: 100, bottom: 100, right: 100) 39 | } 40 | func scrollTrigerPaddingInCollectionView(_ collectionView: UICollectionView) -> UIEdgeInsets { 41 | return .zero 42 | } 43 | func scrollSpeedValueInCollectionView(_ collectionView: UICollectionView) -> CGFloat { 44 | return 10 45 | } 46 | } 47 | 48 | public extension RAReorderableLayoutDelegate { 49 | func collectionView(_ collectionView: UICollectionView, at: IndexPath, willMoveTo toIndexPath: IndexPath) {} 50 | func collectionView(_ collectionView: UICollectionView, at: IndexPath, didMoveTo toIndexPath: IndexPath) {} 51 | func collectionView(_ collectionView: UICollectionView, allowMoveAt indexPath: IndexPath) -> Bool { 52 | return true 53 | } 54 | func collectionView(_ collectionView: UICollectionView, at: IndexPath, canMoveTo: IndexPath) -> Bool { 55 | return true 56 | } 57 | 58 | func collectionView(_ collectionView: UICollectionView, collectionView layout: RAReorderableLayout, willBeginDraggingItemAt indexPath: IndexPath) {} 59 | func collectionView(_ collectionView: UICollectionView, collectionView layout: RAReorderableLayout, didBeginDraggingItemAt indexPath: IndexPath) {} 60 | func collectionView(_ collectionView: UICollectionView, collectionView layout: RAReorderableLayout, willEndDraggingItemTo indexPath: IndexPath) {} 61 | func collectionView(_ collectionView: UICollectionView, collectionView layout: RAReorderableLayout, didEndDraggingItemTo indexPath: IndexPath) {} 62 | } 63 | 64 | open class RAReorderableLayout: UICollectionViewFlowLayout, UIGestureRecognizerDelegate { 65 | 66 | fileprivate enum direction { 67 | case toTop 68 | case toEnd 69 | case stay 70 | 71 | fileprivate func scrollValue(_ speedValue: CGFloat, percentage: CGFloat) -> CGFloat { 72 | var value: CGFloat = 0.0 73 | switch self { 74 | case .toTop: 75 | value = -speedValue 76 | case .toEnd: 77 | value = speedValue 78 | case .stay: 79 | return 0 80 | } 81 | 82 | let proofedPercentage: CGFloat = max(min(1.0, percentage), 0) 83 | return value * proofedPercentage 84 | } 85 | } 86 | 87 | public weak var delegate: RAReorderableLayoutDelegate? { 88 | get { return collectionView?.delegate as? RAReorderableLayoutDelegate } 89 | set { collectionView?.delegate = delegate } 90 | } 91 | 92 | public weak var dataSource: RAReorderableLayoutDataSource? { 93 | set { collectionView?.dataSource = dataSource } 94 | get { return collectionView?.dataSource as? RAReorderableLayoutDataSource } 95 | } 96 | 97 | fileprivate var displayLink: CADisplayLink? 98 | 99 | fileprivate var longPress: UILongPressGestureRecognizer? 100 | 101 | fileprivate var panGesture: UIPanGestureRecognizer? 102 | 103 | fileprivate var continuousScrollDirection: direction = .stay 104 | 105 | fileprivate var cellFakeView: RACellFakeView? 106 | 107 | fileprivate var panTranslation: CGPoint? 108 | 109 | fileprivate var fakeCellCenter: CGPoint? 110 | 111 | fileprivate var trigerInsets = UIEdgeInsetsMake(100.0, 100.0, 100.0, 100.0) 112 | 113 | fileprivate var trigerPadding = UIEdgeInsets.zero 114 | 115 | fileprivate var scrollSpeedValue: CGFloat = 10.0 116 | 117 | fileprivate var offsetFromTop: CGFloat { 118 | let contentOffset = collectionView!.contentOffset 119 | return scrollDirection == .vertical ? contentOffset.y : contentOffset.x 120 | } 121 | 122 | fileprivate var insetsTop: CGFloat { 123 | let contentInsets = collectionView!.contentInset 124 | return scrollDirection == .vertical ? contentInsets.top : contentInsets.left 125 | } 126 | 127 | fileprivate var insetsEnd: CGFloat { 128 | let contentInsets = collectionView!.contentInset 129 | return scrollDirection == .vertical ? contentInsets.bottom : contentInsets.right 130 | } 131 | 132 | fileprivate var contentLength: CGFloat { 133 | let contentSize = collectionView!.contentSize 134 | return scrollDirection == .vertical ? contentSize.height : contentSize.width 135 | } 136 | 137 | fileprivate var collectionViewLength: CGFloat { 138 | let collectionViewSize = collectionView!.bounds.size 139 | return scrollDirection == .vertical ? collectionViewSize.height : collectionViewSize.width 140 | } 141 | 142 | fileprivate var fakeCellTopEdge: CGFloat? { 143 | if let fakeCell = cellFakeView { 144 | return scrollDirection == .vertical ? fakeCell.frame.minY : fakeCell.frame.minX 145 | } 146 | return nil 147 | } 148 | 149 | fileprivate var fakeCellEndEdge: CGFloat? { 150 | if let fakeCell = cellFakeView { 151 | return scrollDirection == .vertical ? fakeCell.frame.maxY : fakeCell.frame.maxX 152 | } 153 | return nil 154 | } 155 | 156 | fileprivate var triggerInsetTop: CGFloat { 157 | return scrollDirection == .vertical ? trigerInsets.top : trigerInsets.left 158 | } 159 | 160 | fileprivate var triggerInsetEnd: CGFloat { 161 | return scrollDirection == .vertical ? trigerInsets.top : trigerInsets.left 162 | } 163 | 164 | fileprivate var triggerPaddingTop: CGFloat { 165 | return scrollDirection == .vertical ? trigerPadding.top : trigerPadding.left 166 | } 167 | 168 | fileprivate var triggerPaddingEnd: CGFloat { 169 | return scrollDirection == .vertical ? trigerPadding.bottom : trigerPadding.right 170 | } 171 | 172 | required public init?(coder aDecoder: NSCoder) { 173 | super.init(coder: aDecoder) 174 | configureObserver() 175 | } 176 | 177 | public override init() { 178 | super.init() 179 | configureObserver() 180 | } 181 | 182 | deinit { 183 | removeObserver(self, forKeyPath: "collectionView") 184 | } 185 | 186 | override open func prepare() { 187 | super.prepare() 188 | 189 | // scroll trigger insets 190 | if let insets = dataSource?.scrollTrigerEdgeInsetsInCollectionView(self.collectionView!) { 191 | trigerInsets = insets 192 | } 193 | 194 | // scroll trier padding 195 | if let padding = dataSource?.scrollTrigerPaddingInCollectionView(self.collectionView!) { 196 | trigerPadding = padding 197 | } 198 | 199 | // scroll speed value 200 | if let speed = dataSource?.scrollSpeedValueInCollectionView(collectionView!) { 201 | scrollSpeedValue = speed 202 | } 203 | } 204 | 205 | override open func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 206 | guard let attributesArray = super.layoutAttributesForElements(in: rect) else { return nil } 207 | 208 | attributesArray.filter { 209 | $0.representedElementCategory == .cell 210 | }.filter { 211 | $0.indexPath == (cellFakeView?.indexPath) 212 | }.forEach { 213 | // reordering cell alpha 214 | 215 | $0.alpha = dataSource?.collectionView(self.collectionView!, reorderingItemAlphaInSection: $0.indexPath.section) ?? 0 216 | } 217 | 218 | return attributesArray 219 | } 220 | 221 | open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 222 | if keyPath == "collectionView" { 223 | setUpGestureRecognizers() 224 | }else { 225 | super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) 226 | } 227 | } 228 | 229 | fileprivate func configureObserver() { 230 | addObserver(self, forKeyPath: "collectionView", options: [], context: nil) 231 | } 232 | 233 | fileprivate func setUpDisplayLink() { 234 | guard displayLink == nil else { 235 | return 236 | } 237 | 238 | displayLink = CADisplayLink(target: self, selector: #selector(RAReorderableLayout.continuousScroll)) 239 | displayLink!.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) 240 | } 241 | 242 | fileprivate func invalidateDisplayLink() { 243 | continuousScrollDirection = .stay 244 | displayLink?.invalidate() 245 | displayLink = nil 246 | } 247 | 248 | // begein scroll 249 | fileprivate func beginScrollIfNeeded() { 250 | if cellFakeView == nil { return } 251 | 252 | if fakeCellTopEdge! <= offsetFromTop + triggerPaddingTop + triggerInsetTop { 253 | continuousScrollDirection = .toTop 254 | setUpDisplayLink() 255 | } else if fakeCellEndEdge! >= offsetFromTop + collectionViewLength - triggerPaddingEnd - triggerInsetEnd { 256 | continuousScrollDirection = .toEnd 257 | setUpDisplayLink() 258 | } else { 259 | invalidateDisplayLink() 260 | } 261 | } 262 | 263 | // move item 264 | fileprivate func moveItemIfNeeded() { 265 | guard let fakeCell = cellFakeView, 266 | let atIndexPath = fakeCell.indexPath, 267 | let toIndexPath = collectionView!.indexPathForItem(at: fakeCell.center) else { 268 | return 269 | } 270 | 271 | guard atIndexPath != toIndexPath else { return } 272 | 273 | // can move item 274 | if let canMove = delegate?.collectionView(collectionView!, at: atIndexPath, canMoveTo: toIndexPath) , !canMove { 275 | return 276 | } 277 | 278 | // will move item 279 | delegate?.collectionView(collectionView!, at: atIndexPath, willMoveTo: toIndexPath) 280 | 281 | let attribute = self.layoutAttributesForItem(at: toIndexPath)! 282 | collectionView!.performBatchUpdates({ 283 | fakeCell.indexPath = toIndexPath 284 | fakeCell.cellFrame = attribute.frame 285 | fakeCell.changeBoundsIfNeeded(attribute.bounds) 286 | 287 | self.collectionView!.deleteItems(at: [atIndexPath]) 288 | self.collectionView!.insertItems(at: [toIndexPath]) 289 | 290 | // did move item 291 | self.delegate?.collectionView(self.collectionView!, at: atIndexPath, didMoveTo: toIndexPath) 292 | }, completion:nil) 293 | } 294 | 295 | internal func continuousScroll() { 296 | guard let fakeCell = cellFakeView else { return } 297 | 298 | let percentage = calcTriggerPercentage() 299 | var scrollRate = continuousScrollDirection.scrollValue(self.scrollSpeedValue, percentage: percentage) 300 | 301 | let offset = offsetFromTop 302 | let length = collectionViewLength 303 | 304 | if contentLength + insetsTop + insetsEnd <= length { 305 | return 306 | } 307 | 308 | if offset + scrollRate <= -insetsTop { 309 | scrollRate = -insetsTop - offset 310 | } else if offset + scrollRate >= contentLength + insetsEnd - length { 311 | scrollRate = contentLength + insetsEnd - length - offset 312 | } 313 | 314 | collectionView!.performBatchUpdates({ 315 | if self.scrollDirection == .vertical { 316 | self.fakeCellCenter?.y += scrollRate 317 | fakeCell.center.y = self.fakeCellCenter!.y + self.panTranslation!.y 318 | self.collectionView?.contentOffset.y += scrollRate 319 | } else { 320 | self.fakeCellCenter?.x += scrollRate 321 | fakeCell.center.x = self.fakeCellCenter!.x + self.panTranslation!.x 322 | self.collectionView?.contentOffset.x += scrollRate 323 | } 324 | }, completion: nil) 325 | 326 | moveItemIfNeeded() 327 | } 328 | 329 | fileprivate func calcTriggerPercentage() -> CGFloat { 330 | guard cellFakeView != nil else { return 0 } 331 | 332 | let offset = offsetFromTop 333 | let offsetEnd = offsetFromTop + collectionViewLength 334 | let paddingEnd = triggerPaddingEnd 335 | 336 | var percentage: CGFloat = 0 337 | 338 | if self.continuousScrollDirection == .toTop { 339 | if let fakeCellEdge = fakeCellTopEdge { 340 | percentage = 1.0 - ((fakeCellEdge - (offset + triggerPaddingTop)) / triggerInsetTop) 341 | } 342 | }else if continuousScrollDirection == .toEnd { 343 | if let fakeCellEdge = fakeCellEndEdge { 344 | percentage = 1.0 - (((insetsTop + offsetEnd - paddingEnd) - (fakeCellEdge + insetsTop)) / triggerInsetEnd) 345 | } 346 | } 347 | 348 | percentage = min(1.0, percentage) 349 | percentage = max(0, percentage) 350 | return percentage 351 | } 352 | 353 | // gesture recognizers 354 | fileprivate func setUpGestureRecognizers() { 355 | guard let collectionView = collectionView else { return } 356 | guard longPress == nil && panGesture == nil else {return } 357 | 358 | longPress = UILongPressGestureRecognizer(target: self, action: #selector(RAReorderableLayout.handleLongPress(_:))) 359 | panGesture = UIPanGestureRecognizer(target: self, action: #selector(RAReorderableLayout.handlePanGesture(_:))) 360 | longPress?.delegate = self 361 | panGesture?.delegate = self 362 | panGesture?.maximumNumberOfTouches = 1 363 | let gestures: NSArray! = collectionView.gestureRecognizers as NSArray! 364 | gestures.enumerateObjects(options: []) { gestureRecognizer, index, finish in 365 | if gestureRecognizer is UILongPressGestureRecognizer { 366 | (gestureRecognizer as AnyObject).require(toFail: self.longPress!) 367 | } 368 | collectionView.addGestureRecognizer(self.longPress!) 369 | collectionView.addGestureRecognizer(self.panGesture!) 370 | } 371 | } 372 | 373 | open func cancelDrag() { 374 | cancelDrag(nil) 375 | } 376 | 377 | fileprivate func cancelDrag(_ toIndexPath: IndexPath!) { 378 | guard cellFakeView != nil else { return } 379 | 380 | // will end drag item 381 | self.delegate?.collectionView(self.collectionView!, collectionView: self, willEndDraggingItemTo: toIndexPath) 382 | 383 | collectionView?.scrollsToTop = true 384 | 385 | fakeCellCenter = nil 386 | 387 | invalidateDisplayLink() 388 | 389 | cellFakeView!.pushBackView { 390 | self.cellFakeView!.removeFromSuperview() 391 | self.cellFakeView = nil 392 | self.invalidateLayout() 393 | 394 | // did end drag item 395 | self.delegate?.collectionView(self.collectionView!, collectionView: self, didEndDraggingItemTo: toIndexPath) 396 | } 397 | } 398 | 399 | // long press gesture 400 | internal func handleLongPress(_ longPress: UILongPressGestureRecognizer!) { 401 | let location = longPress.location(in: collectionView) 402 | var indexPath: IndexPath? = collectionView?.indexPathForItem(at: location) 403 | 404 | if let cellFakeView = cellFakeView { 405 | indexPath = cellFakeView.indexPath 406 | } 407 | 408 | if indexPath == nil { return } 409 | 410 | switch longPress.state { 411 | case .began: 412 | // will begin drag item 413 | delegate?.collectionView(self.collectionView!, collectionView: self, willBeginDraggingItemAt: indexPath!) 414 | collectionView?.scrollsToTop = false 415 | 416 | let currentCell = collectionView?.cellForItem(at: indexPath!) 417 | 418 | cellFakeView = RACellFakeView(cell: currentCell!) 419 | cellFakeView!.indexPath = indexPath 420 | cellFakeView!.originalCenter = currentCell?.center 421 | cellFakeView!.cellFrame = layoutAttributesForItem(at: indexPath!)!.frame 422 | collectionView?.addSubview(cellFakeView!) 423 | 424 | fakeCellCenter = cellFakeView!.center 425 | 426 | invalidateLayout() 427 | 428 | cellFakeView?.pushFowardView() 429 | 430 | // did begin drag item 431 | delegate?.collectionView(self.collectionView!, collectionView: self, didBeginDraggingItemAt: indexPath!) 432 | 433 | case .cancelled, .ended: 434 | cancelDrag(indexPath) 435 | default: 436 | break 437 | } 438 | } 439 | 440 | // pan gesture 441 | func handlePanGesture(_ pan: UIPanGestureRecognizer!) { 442 | panTranslation = pan.translation(in: collectionView!) 443 | if let cellFakeView = cellFakeView, 444 | let fakeCellCenter = fakeCellCenter, 445 | let panTranslation = panTranslation { 446 | switch pan.state { 447 | case .changed: 448 | cellFakeView.center.x = fakeCellCenter.x + panTranslation.x 449 | cellFakeView.center.y = fakeCellCenter.y + panTranslation.y 450 | 451 | beginScrollIfNeeded() 452 | moveItemIfNeeded() 453 | case .cancelled, .ended: 454 | invalidateDisplayLink() 455 | default: 456 | break 457 | } 458 | } 459 | } 460 | 461 | // gesture recognize delegate 462 | open func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { 463 | // allow move item 464 | let location = gestureRecognizer.location(in: collectionView) 465 | if let indexPath = collectionView?.indexPathForItem(at: location) , 466 | delegate?.collectionView(self.collectionView!, allowMoveAt: indexPath) == false { 467 | return false 468 | } 469 | 470 | switch gestureRecognizer { 471 | case longPress: 472 | return !(collectionView!.panGestureRecognizer.state != .possible && collectionView!.panGestureRecognizer.state != .failed) 473 | case panGesture: 474 | return !(longPress!.state == .possible || longPress!.state == .failed) 475 | default: 476 | return true 477 | } 478 | } 479 | 480 | open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { 481 | switch gestureRecognizer { 482 | case panGesture: 483 | return otherGestureRecognizer == longPress 484 | case collectionView?.panGestureRecognizer: 485 | return (longPress!.state != .possible || longPress!.state != .failed) 486 | default: 487 | return true 488 | } 489 | } 490 | } 491 | 492 | private class RACellFakeView: UIView { 493 | 494 | weak var cell: UICollectionViewCell? 495 | 496 | var cellFakeImageView: UIImageView? 497 | 498 | var cellFakeHightedView: UIImageView? 499 | 500 | fileprivate var indexPath: IndexPath? 501 | 502 | fileprivate var originalCenter: CGPoint? 503 | 504 | fileprivate var cellFrame: CGRect? 505 | 506 | required init?(coder aDecoder: NSCoder) { 507 | super.init(coder: aDecoder) 508 | } 509 | 510 | init(cell: UICollectionViewCell) { 511 | super.init(frame: cell.frame) 512 | 513 | self.cell = cell 514 | 515 | layer.shadowColor = UIColor.black.cgColor 516 | layer.shadowOffset = CGSize(width: 0, height: 0) 517 | layer.shadowOpacity = 0 518 | layer.shadowRadius = 5.0 519 | layer.shouldRasterize = false 520 | 521 | cellFakeImageView = UIImageView(frame: self.bounds) 522 | cellFakeImageView?.contentMode = UIViewContentMode.scaleAspectFill 523 | cellFakeImageView?.autoresizingMask = [.flexibleWidth , .flexibleHeight] 524 | 525 | cellFakeHightedView = UIImageView(frame: self.bounds) 526 | cellFakeHightedView?.contentMode = UIViewContentMode.scaleAspectFill 527 | cellFakeHightedView?.autoresizingMask = [.flexibleWidth , .flexibleHeight] 528 | 529 | cell.isHighlighted = true 530 | cellFakeHightedView?.image = getCellImage() 531 | cell.isHighlighted = false 532 | cellFakeImageView?.image = getCellImage() 533 | 534 | addSubview(cellFakeImageView!) 535 | addSubview(cellFakeHightedView!) 536 | } 537 | 538 | func changeBoundsIfNeeded(_ bounds: CGRect) { 539 | if self.bounds.equalTo(bounds) { return } 540 | 541 | UIView.animate( 542 | withDuration: 0.3, 543 | delay: 0, 544 | options: [.curveEaseInOut, .beginFromCurrentState], 545 | animations: { 546 | self.bounds = bounds 547 | }, 548 | completion: nil 549 | ) 550 | } 551 | 552 | func pushFowardView() { 553 | UIView.animate( 554 | withDuration: 0.3, 555 | delay: 0, 556 | options: [.curveEaseInOut, .beginFromCurrentState], 557 | animations: { 558 | self.center = self.originalCenter! 559 | self.transform = CGAffineTransform(scaleX: 1.1, y: 1.1) 560 | self.cellFakeHightedView!.alpha = 0; 561 | let shadowAnimation = CABasicAnimation(keyPath: "shadowOpacity") 562 | shadowAnimation.fromValue = 0 563 | shadowAnimation.toValue = 0.7 564 | shadowAnimation.isRemovedOnCompletion = false 565 | shadowAnimation.fillMode = kCAFillModeForwards 566 | self.layer.add(shadowAnimation, forKey: "applyShadow") 567 | }, 568 | completion: { _ in 569 | self.cellFakeHightedView?.removeFromSuperview() 570 | } 571 | ) 572 | } 573 | 574 | func pushBackView(_ completion: (()->Void)?) { 575 | UIView.animate( 576 | withDuration: 0.3, 577 | delay: 0, 578 | options: [.curveEaseInOut, .beginFromCurrentState], 579 | animations: { 580 | self.transform = CGAffineTransform.identity 581 | self.frame = self.cellFrame! 582 | let shadowAnimation = CABasicAnimation(keyPath: "shadowOpacity") 583 | shadowAnimation.fromValue = 0.7 584 | shadowAnimation.toValue = 0 585 | shadowAnimation.isRemovedOnCompletion = false 586 | shadowAnimation.fillMode = kCAFillModeForwards 587 | self.layer.add(shadowAnimation, forKey: "removeShadow") 588 | }, 589 | completion: { _ in 590 | completion?() 591 | } 592 | ) 593 | } 594 | 595 | fileprivate func getCellImage() -> UIImage { 596 | UIGraphicsBeginImageContextWithOptions(cell!.bounds.size, false, UIScreen.main.scale * 2) 597 | defer { UIGraphicsEndImageContext() } 598 | cell!.drawHierarchy(in: cell!.bounds, afterScreenUpdates: true) 599 | 600 | return UIGraphicsGetImageFromCurrentImageContext()! 601 | } 602 | } 603 | 604 | // Convenience method 605 | private func ~= (obj:NSObjectProtocol?, r:UIGestureRecognizer) -> Bool { 606 | return r.isEqual(obj) 607 | } 608 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RAReorderableLayout 2 | ======================= 3 | 4 | #### A UICollectionView layout which you can move items with drag and drop. 5 | 6 | 7 | ## Screen shots 8 | ![screen shot1](https://github.com/ra1028/RAReorderableLayout/raw/master/Assets/screenshot1.png) 9 | ![screen shot2](https://github.com/ra1028/RAReorderableLayout/raw/master/Assets/screenshot2.png) 10 | 11 | 12 | ## Animation 13 | ![animated gif](https://github.com/ra1028/RAReorderableLayout/raw/master/Assets/animation.gif) 14 | 15 | ## Requirements 16 | - Swift 3.0 / Xcode 8 17 | OS X 10.9 or later 18 | iOS 8.0 or later 19 | watchOS 2.0 or later 20 | tvOS 9.0 or later 21 | 22 | _Still wanna use swift2.2 or 2.3?_ 23 | -> You can use [0.5.0](https://github.com/ra1028/RAReorderableLayout/tree/0.5.0) instead. 24 | 25 | ## Installation 26 | __iOS8 or later__ 27 | 28 | ### CocoaPods 29 | ```ruby 30 | # Podfile 31 | use_frameworks! 32 | 33 | target 'YOUR_TARGET_NAME' do 34 | pod 'RAReorderableLayout' 35 | end 36 | 37 | ``` 38 | ### Carthage 39 | ```ruby 40 | # Cartfile 41 | github "ra1028/RAReorderableLayout" 42 | ``` 43 | 44 | ## Usage 45 | Setup your collection view to use RAReorderableLayout. 46 | You must reorder cells information array in RAReorderableLayoutDelegate protocol to support reordering capability. 47 | Specifically, please refer to Demo-project. 48 | 49 | 50 | ## Protocol 51 | 52 | Delegate 53 | ``` 54 | optional func collectionView(collectionView: UICollectionView, atIndexPath: NSIndexPath, willMoveToIndexPath toIndexPath: NSIndexPath) 55 | optional func collectionView(collectionView: UICollectionView, atIndexPath: NSIndexPath, didMoveToIndexPath toIndexPath: NSIndexPath) 56 | 57 | optional func collectionView(collectionView: UICollectionView, allowMoveAtIndexPath indexPath: NSIndexPath) -> Bool 58 | optional func collectionView(collectionView: UICollectionView, atIndexPath: NSIndexPath, canMoveToIndexPath: NSIndexPath) -> Bool 59 | 60 | optional func collectionView(collectionView: UICollectionView, collectionViewLayout layout: RAReorderableLayout, willBeginDraggingItemAtIndexPath indexPath: NSIndexPath) 61 | optional func collectionView(collectionView: UICollectionView, collectionViewLayout layout: RAReorderableLayout, didBeginDraggingItemAtIndexPath indexPath: NSIndexPath) 62 | optional func collectionView(collectionView: UICollectionView, collectionViewLayout layout: RAReorderableLayout, willEndDraggingItemToIndexPath indexPath: NSIndexPath) 63 | optional func collectionView(collectionView: UICollectionView, collectionViewLayout layout: RAReorderableLayout, didEndDraggingItemToIndexPath indexPath: NSIndexPath) 64 | ``` 65 | 66 | Datasource 67 | ``` 68 | optional func collectionView(collectionView: UICollectionView, reorderingItemAlphaInSection section: Int) -> CGFloat 69 | optional func scrollTrigerEdgeInsetsInCollectionView(collectionView: UICollectionView) -> UIEdgeInsets 70 | optional func scrollTrigerPaddingInCollectionView(collectionView: UICollectionView) -> UIEdgeInsets 71 | optional func scrollSpeedValueInCollectionView(collectionView: UICollectionView) -> CGFloat 72 | ``` 73 | 74 | ## License 75 | RAReorderableLayout is available under the MIT license. See the LICENSE file for more info. 76 | --------------------------------------------------------------------------------