├── .gitignore ├── Example ├── Example.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Example │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-60.png │ │ ├── Icon-60@2x-1.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x-1.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-72.png │ │ ├── Icon-72@2x.png │ │ ├── Icon-76.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-Small-40.png │ │ ├── Icon-Small-40@2x.png │ │ ├── Icon-Small-40@3x.png │ │ ├── Icon-Small-50.png │ │ ├── Icon-Small-50@2x.png │ │ ├── Icon-Small.png │ │ ├── Icon-Small@2x.png │ │ ├── Icon-Small@3x.png │ │ ├── Icon.png │ │ ├── Icon@2x.png │ │ └── iTunesArtwork@2x.png │ ├── Contents.json │ ├── samurai.imageset │ │ ├── Contents.json │ │ └── samurai@2x.png │ ├── samurai2.imageset │ │ ├── Contents.json │ │ └── samurai2@2x.png │ └── splash_samurai.imageset │ │ ├── Contents.json │ │ ├── splash_samurai.png │ │ ├── splash_samurai@2x.png │ │ └── splash_samurai@3x.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── ModalViewController.swift │ └── ViewController.swift ├── LICENSE ├── README.md ├── SamuraiTransition.podspec ├── SamuraiTransition.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── SamuraiTransition.xcscheme └── SamuraiTransition ├── Info.plist ├── SamuraiTransition.h ├── SamuraiTransition.swift ├── ViewController └── SamuraiViewController.swift └── Zan ├── Config ├── ChoppedZanConfig.swift ├── CircleZanConfig.swift ├── CrossZanConfig.swift ├── DiagonallyZanConfig.swift ├── HorizontalZanConfig.swift ├── JaggedZanConfig.swift ├── RectangleZanConfig.swift ├── SamuraiConfigProtocol.swift ├── ShreddedZanConfig.swift ├── TriangleZanConfig.swift ├── VerticalZanConfig.swift ├── XZanConfig.swift ├── ZanLineProtocol.swift ├── ZanViewConfig.swift └── ZanViewConfigProtocol.swift └── Zan.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C2F716691DE9568700480CAB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F716681DE9568700480CAB /* AppDelegate.swift */; }; 11 | C2F7166B1DE9568700480CAB /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F7166A1DE9568700480CAB /* ViewController.swift */; }; 12 | C2F7166E1DE9568700480CAB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C2F7166C1DE9568700480CAB /* Main.storyboard */; }; 13 | C2F716701DE9568700480CAB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C2F7166F1DE9568700480CAB /* Assets.xcassets */; }; 14 | C2F716731DE9568700480CAB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C2F716711DE9568700480CAB /* LaunchScreen.storyboard */; }; 15 | C2F716821DE956A800480CAB /* SamuraiTransition.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2F7167F1DE9569700480CAB /* SamuraiTransition.framework */; }; 16 | C2F7168A1DE965E000480CAB /* ModalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F716891DE965E000480CAB /* ModalViewController.swift */; }; 17 | C2F949FB1DF1328900B5D736 /* SamuraiTransition.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = C2F7167F1DE9569700480CAB /* SamuraiTransition.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | C2F7167E1DE9569700480CAB /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = C2F7167A1DE9569600480CAB /* SamuraiTransition.xcodeproj */; 24 | proxyType = 2; 25 | remoteGlobalIDString = C2F716511DE9565000480CAB; 26 | remoteInfo = SamuraiTransition; 27 | }; 28 | C2F716801DE956A100480CAB /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = C2F7167A1DE9569600480CAB /* SamuraiTransition.xcodeproj */; 31 | proxyType = 1; 32 | remoteGlobalIDString = C2F716501DE9565000480CAB; 33 | remoteInfo = SamuraiTransition; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXCopyFilesBuildPhase section */ 38 | C2F949FA1DF1327C00B5D736 /* CopyFiles */ = { 39 | isa = PBXCopyFilesBuildPhase; 40 | buildActionMask = 2147483647; 41 | dstPath = ""; 42 | dstSubfolderSpec = 10; 43 | files = ( 44 | C2F949FB1DF1328900B5D736 /* SamuraiTransition.framework in CopyFiles */, 45 | ); 46 | runOnlyForDeploymentPostprocessing = 0; 47 | }; 48 | /* End PBXCopyFilesBuildPhase section */ 49 | 50 | /* Begin PBXFileReference section */ 51 | C2F716651DE9568700480CAB /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | C2F716681DE9568700480CAB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 53 | C2F7166A1DE9568700480CAB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 54 | C2F7166D1DE9568700480CAB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | C2F7166F1DE9568700480CAB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | C2F716721DE9568700480CAB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 57 | C2F716741DE9568700480CAB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | C2F7167A1DE9569600480CAB /* SamuraiTransition.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SamuraiTransition.xcodeproj; path = ../SamuraiTransition.xcodeproj; sourceTree = ""; }; 59 | C2F716891DE965E000480CAB /* ModalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalViewController.swift; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | C2F716621DE9568700480CAB /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | C2F716821DE956A800480CAB /* SamuraiTransition.framework in Frameworks */, 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | /* End PBXFrameworksBuildPhase section */ 72 | 73 | /* Begin PBXGroup section */ 74 | C2F7165C1DE9568700480CAB = { 75 | isa = PBXGroup; 76 | children = ( 77 | C2F716671DE9568700480CAB /* Example */, 78 | C2F716661DE9568700480CAB /* Products */, 79 | C2F7167A1DE9569600480CAB /* SamuraiTransition.xcodeproj */, 80 | ); 81 | sourceTree = ""; 82 | }; 83 | C2F716661DE9568700480CAB /* Products */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | C2F716651DE9568700480CAB /* Example.app */, 87 | ); 88 | name = Products; 89 | sourceTree = ""; 90 | }; 91 | C2F716671DE9568700480CAB /* Example */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | C2F716681DE9568700480CAB /* AppDelegate.swift */, 95 | C2F7166A1DE9568700480CAB /* ViewController.swift */, 96 | C2F716891DE965E000480CAB /* ModalViewController.swift */, 97 | C2F7166C1DE9568700480CAB /* Main.storyboard */, 98 | C2F7166F1DE9568700480CAB /* Assets.xcassets */, 99 | C2F716711DE9568700480CAB /* LaunchScreen.storyboard */, 100 | C2F716741DE9568700480CAB /* Info.plist */, 101 | ); 102 | path = Example; 103 | sourceTree = ""; 104 | }; 105 | C2F7167B1DE9569600480CAB /* Products */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | C2F7167F1DE9569700480CAB /* SamuraiTransition.framework */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | /* End PBXGroup section */ 114 | 115 | /* Begin PBXNativeTarget section */ 116 | C2F716641DE9568700480CAB /* Example */ = { 117 | isa = PBXNativeTarget; 118 | buildConfigurationList = C2F716771DE9568700480CAB /* Build configuration list for PBXNativeTarget "Example" */; 119 | buildPhases = ( 120 | C2F716611DE9568700480CAB /* Sources */, 121 | C2F716621DE9568700480CAB /* Frameworks */, 122 | C2F716631DE9568700480CAB /* Resources */, 123 | C2F949FA1DF1327C00B5D736 /* CopyFiles */, 124 | ); 125 | buildRules = ( 126 | ); 127 | dependencies = ( 128 | C2F716811DE956A100480CAB /* PBXTargetDependency */, 129 | ); 130 | name = Example; 131 | productName = Example; 132 | productReference = C2F716651DE9568700480CAB /* Example.app */; 133 | productType = "com.apple.product-type.application"; 134 | }; 135 | /* End PBXNativeTarget section */ 136 | 137 | /* Begin PBXProject section */ 138 | C2F7165D1DE9568700480CAB /* Project object */ = { 139 | isa = PBXProject; 140 | attributes = { 141 | LastSwiftUpdateCheck = 0810; 142 | LastUpgradeCheck = 0940; 143 | ORGANIZATIONNAME = hachinobu; 144 | TargetAttributes = { 145 | C2F716641DE9568700480CAB = { 146 | CreatedOnToolsVersion = 8.1; 147 | LastSwiftMigration = 1020; 148 | ProvisioningStyle = Automatic; 149 | }; 150 | }; 151 | }; 152 | buildConfigurationList = C2F716601DE9568700480CAB /* Build configuration list for PBXProject "Example" */; 153 | compatibilityVersion = "Xcode 3.2"; 154 | developmentRegion = en; 155 | hasScannedForEncodings = 0; 156 | knownRegions = ( 157 | en, 158 | Base, 159 | ); 160 | mainGroup = C2F7165C1DE9568700480CAB; 161 | productRefGroup = C2F716661DE9568700480CAB /* Products */; 162 | projectDirPath = ""; 163 | projectReferences = ( 164 | { 165 | ProductGroup = C2F7167B1DE9569600480CAB /* Products */; 166 | ProjectRef = C2F7167A1DE9569600480CAB /* SamuraiTransition.xcodeproj */; 167 | }, 168 | ); 169 | projectRoot = ""; 170 | targets = ( 171 | C2F716641DE9568700480CAB /* Example */, 172 | ); 173 | }; 174 | /* End PBXProject section */ 175 | 176 | /* Begin PBXReferenceProxy section */ 177 | C2F7167F1DE9569700480CAB /* SamuraiTransition.framework */ = { 178 | isa = PBXReferenceProxy; 179 | fileType = wrapper.framework; 180 | path = SamuraiTransition.framework; 181 | remoteRef = C2F7167E1DE9569700480CAB /* PBXContainerItemProxy */; 182 | sourceTree = BUILT_PRODUCTS_DIR; 183 | }; 184 | /* End PBXReferenceProxy section */ 185 | 186 | /* Begin PBXResourcesBuildPhase section */ 187 | C2F716631DE9568700480CAB /* Resources */ = { 188 | isa = PBXResourcesBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | C2F716731DE9568700480CAB /* LaunchScreen.storyboard in Resources */, 192 | C2F716701DE9568700480CAB /* Assets.xcassets in Resources */, 193 | C2F7166E1DE9568700480CAB /* Main.storyboard in Resources */, 194 | ); 195 | runOnlyForDeploymentPostprocessing = 0; 196 | }; 197 | /* End PBXResourcesBuildPhase section */ 198 | 199 | /* Begin PBXSourcesBuildPhase section */ 200 | C2F716611DE9568700480CAB /* Sources */ = { 201 | isa = PBXSourcesBuildPhase; 202 | buildActionMask = 2147483647; 203 | files = ( 204 | C2F7168A1DE965E000480CAB /* ModalViewController.swift in Sources */, 205 | C2F7166B1DE9568700480CAB /* ViewController.swift in Sources */, 206 | C2F716691DE9568700480CAB /* AppDelegate.swift in Sources */, 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | }; 210 | /* End PBXSourcesBuildPhase section */ 211 | 212 | /* Begin PBXTargetDependency section */ 213 | C2F716811DE956A100480CAB /* PBXTargetDependency */ = { 214 | isa = PBXTargetDependency; 215 | name = SamuraiTransition; 216 | targetProxy = C2F716801DE956A100480CAB /* PBXContainerItemProxy */; 217 | }; 218 | /* End PBXTargetDependency section */ 219 | 220 | /* Begin PBXVariantGroup section */ 221 | C2F7166C1DE9568700480CAB /* Main.storyboard */ = { 222 | isa = PBXVariantGroup; 223 | children = ( 224 | C2F7166D1DE9568700480CAB /* Base */, 225 | ); 226 | name = Main.storyboard; 227 | sourceTree = ""; 228 | }; 229 | C2F716711DE9568700480CAB /* LaunchScreen.storyboard */ = { 230 | isa = PBXVariantGroup; 231 | children = ( 232 | C2F716721DE9568700480CAB /* Base */, 233 | ); 234 | name = LaunchScreen.storyboard; 235 | sourceTree = ""; 236 | }; 237 | /* End PBXVariantGroup section */ 238 | 239 | /* Begin XCBuildConfiguration section */ 240 | C2F716751DE9568700480CAB /* Debug */ = { 241 | isa = XCBuildConfiguration; 242 | buildSettings = { 243 | ALWAYS_SEARCH_USER_PATHS = NO; 244 | CLANG_ANALYZER_NONNULL = YES; 245 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 246 | CLANG_CXX_LIBRARY = "libc++"; 247 | CLANG_ENABLE_MODULES = YES; 248 | CLANG_ENABLE_OBJC_ARC = YES; 249 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 250 | CLANG_WARN_BOOL_CONVERSION = YES; 251 | CLANG_WARN_COMMA = YES; 252 | CLANG_WARN_CONSTANT_CONVERSION = YES; 253 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 254 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 255 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 256 | CLANG_WARN_EMPTY_BODY = YES; 257 | CLANG_WARN_ENUM_CONVERSION = YES; 258 | CLANG_WARN_INFINITE_RECURSION = YES; 259 | CLANG_WARN_INT_CONVERSION = YES; 260 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 261 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 262 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 263 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 264 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 265 | CLANG_WARN_STRICT_PROTOTYPES = YES; 266 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 267 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 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 = NO; 272 | DEBUG_INFORMATION_FORMAT = dwarf; 273 | ENABLE_STRICT_OBJC_MSGSEND = YES; 274 | ENABLE_TESTABILITY = YES; 275 | GCC_C_LANGUAGE_STANDARD = gnu99; 276 | GCC_DYNAMIC_NO_PIC = NO; 277 | GCC_NO_COMMON_BLOCKS = YES; 278 | GCC_OPTIMIZATION_LEVEL = 0; 279 | GCC_PREPROCESSOR_DEFINITIONS = ( 280 | "DEBUG=1", 281 | "$(inherited)", 282 | ); 283 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 284 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 285 | GCC_WARN_UNDECLARED_SELECTOR = YES; 286 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 287 | GCC_WARN_UNUSED_FUNCTION = YES; 288 | GCC_WARN_UNUSED_VARIABLE = YES; 289 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 290 | MTL_ENABLE_DEBUG_INFO = YES; 291 | ONLY_ACTIVE_ARCH = YES; 292 | SDKROOT = iphoneos; 293 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 294 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 295 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 296 | SWIFT_VERSION = 4.0; 297 | }; 298 | name = Debug; 299 | }; 300 | C2F716761DE9568700480CAB /* Release */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ALWAYS_SEARCH_USER_PATHS = NO; 304 | CLANG_ANALYZER_NONNULL = YES; 305 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 306 | CLANG_CXX_LIBRARY = "libc++"; 307 | CLANG_ENABLE_MODULES = YES; 308 | CLANG_ENABLE_OBJC_ARC = YES; 309 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 310 | CLANG_WARN_BOOL_CONVERSION = YES; 311 | CLANG_WARN_COMMA = YES; 312 | CLANG_WARN_CONSTANT_CONVERSION = YES; 313 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 314 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 315 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 316 | CLANG_WARN_EMPTY_BODY = YES; 317 | CLANG_WARN_ENUM_CONVERSION = YES; 318 | CLANG_WARN_INFINITE_RECURSION = YES; 319 | CLANG_WARN_INT_CONVERSION = YES; 320 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 321 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 322 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 323 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 324 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 325 | CLANG_WARN_STRICT_PROTOTYPES = YES; 326 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 333 | ENABLE_NS_ASSERTIONS = NO; 334 | ENABLE_STRICT_OBJC_MSGSEND = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_NO_COMMON_BLOCKS = YES; 337 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 338 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 339 | GCC_WARN_UNDECLARED_SELECTOR = YES; 340 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 341 | GCC_WARN_UNUSED_FUNCTION = YES; 342 | GCC_WARN_UNUSED_VARIABLE = YES; 343 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 344 | MTL_ENABLE_DEBUG_INFO = NO; 345 | SDKROOT = iphoneos; 346 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 347 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 348 | SWIFT_VERSION = 4.0; 349 | VALIDATE_PRODUCT = YES; 350 | }; 351 | name = Release; 352 | }; 353 | C2F716781DE9568700480CAB /* Debug */ = { 354 | isa = XCBuildConfiguration; 355 | buildSettings = { 356 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 357 | INFOPLIST_FILE = Example/Info.plist; 358 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 359 | PRODUCT_BUNDLE_IDENTIFIER = hachinobu.SamuraiTransition.Example; 360 | PRODUCT_NAME = "$(TARGET_NAME)"; 361 | SWIFT_VERSION = 5.0; 362 | }; 363 | name = Debug; 364 | }; 365 | C2F716791DE9568700480CAB /* Release */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 369 | INFOPLIST_FILE = Example/Info.plist; 370 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 371 | PRODUCT_BUNDLE_IDENTIFIER = hachinobu.SamuraiTransition.Example; 372 | PRODUCT_NAME = "$(TARGET_NAME)"; 373 | SWIFT_VERSION = 5.0; 374 | }; 375 | name = Release; 376 | }; 377 | /* End XCBuildConfiguration section */ 378 | 379 | /* Begin XCConfigurationList section */ 380 | C2F716601DE9568700480CAB /* Build configuration list for PBXProject "Example" */ = { 381 | isa = XCConfigurationList; 382 | buildConfigurations = ( 383 | C2F716751DE9568700480CAB /* Debug */, 384 | C2F716761DE9568700480CAB /* Release */, 385 | ); 386 | defaultConfigurationIsVisible = 0; 387 | defaultConfigurationName = Release; 388 | }; 389 | C2F716771DE9568700480CAB /* Build configuration list for PBXNativeTarget "Example" */ = { 390 | isa = XCConfigurationList; 391 | buildConfigurations = ( 392 | C2F716781DE9568700480CAB /* Debug */, 393 | C2F716791DE9568700480CAB /* Release */, 394 | ); 395 | defaultConfigurationIsVisible = 0; 396 | defaultConfigurationName = Release; 397 | }; 398 | /* End XCConfigurationList section */ 399 | }; 400 | rootObject = C2F7165D1DE9568700480CAB /* Project object */; 401 | } 402 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by Takahiro Nishinobu on 2016/11/26. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | UINavigationBar.appearance().barTintColor = UIColor(red: 224/255.0, green: 224/255.0, blue: 228/255.0, alpha: 1.0) 20 | return true 21 | } 22 | 23 | func applicationWillResignActive(_ application: UIApplication) { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 26 | } 27 | 28 | func applicationDidEnterBackground(_ application: UIApplication) { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | func applicationWillEnterForeground(_ application: UIApplication) { 34 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | func applicationDidBecomeActive(_ application: UIApplication) { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | func applicationWillTerminate(_ application: UIApplication) { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | 46 | } 47 | 48 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "size" : "20x20", 10 | "idiom" : "iphone", 11 | "filename" : "Icon-60.png", 12 | "scale" : "3x" 13 | }, 14 | { 15 | "size" : "29x29", 16 | "idiom" : "iphone", 17 | "filename" : "Icon-Small.png", 18 | "scale" : "1x" 19 | }, 20 | { 21 | "idiom" : "iphone", 22 | "size" : "29x29", 23 | "scale" : "2x" 24 | }, 25 | { 26 | "idiom" : "iphone", 27 | "size" : "29x29", 28 | "scale" : "3x" 29 | }, 30 | { 31 | "size" : "40x40", 32 | "idiom" : "iphone", 33 | "filename" : "Icon-Small-40@2x.png", 34 | "scale" : "2x" 35 | }, 36 | { 37 | "size" : "40x40", 38 | "idiom" : "iphone", 39 | "filename" : "Icon-Small-40@3x.png", 40 | "scale" : "3x" 41 | }, 42 | { 43 | "size" : "57x57", 44 | "idiom" : "iphone", 45 | "filename" : "Icon.png", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "size" : "57x57", 50 | "idiom" : "iphone", 51 | "filename" : "Icon@2x.png", 52 | "scale" : "2x" 53 | }, 54 | { 55 | "size" : "60x60", 56 | "idiom" : "iphone", 57 | "filename" : "Icon-60@2x-1.png", 58 | "scale" : "2x" 59 | }, 60 | { 61 | "size" : "60x60", 62 | "idiom" : "iphone", 63 | "filename" : "Icon-60@3x-1.png", 64 | "scale" : "3x" 65 | }, 66 | { 67 | "idiom" : "ipad", 68 | "size" : "20x20", 69 | "scale" : "1x" 70 | }, 71 | { 72 | "idiom" : "ipad", 73 | "size" : "20x20", 74 | "scale" : "2x" 75 | }, 76 | { 77 | "idiom" : "ipad", 78 | "size" : "29x29", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "idiom" : "ipad", 83 | "size" : "29x29", 84 | "scale" : "2x" 85 | }, 86 | { 87 | "size" : "40x40", 88 | "idiom" : "ipad", 89 | "filename" : "Icon-Small-40.png", 90 | "scale" : "1x" 91 | }, 92 | { 93 | "idiom" : "ipad", 94 | "size" : "40x40", 95 | "scale" : "2x" 96 | }, 97 | { 98 | "size" : "50x50", 99 | "idiom" : "ipad", 100 | "filename" : "Icon-Small-50.png", 101 | "scale" : "1x" 102 | }, 103 | { 104 | "size" : "50x50", 105 | "idiom" : "ipad", 106 | "filename" : "Icon-Small-50@2x.png", 107 | "scale" : "2x" 108 | }, 109 | { 110 | "size" : "72x72", 111 | "idiom" : "ipad", 112 | "filename" : "Icon-72.png", 113 | "scale" : "1x" 114 | }, 115 | { 116 | "size" : "72x72", 117 | "idiom" : "ipad", 118 | "filename" : "Icon-72@2x.png", 119 | "scale" : "2x" 120 | }, 121 | { 122 | "size" : "76x76", 123 | "idiom" : "ipad", 124 | "filename" : "Icon-76.png", 125 | "scale" : "1x" 126 | }, 127 | { 128 | "size" : "76x76", 129 | "idiom" : "ipad", 130 | "filename" : "Icon-76@2x.png", 131 | "scale" : "2x" 132 | }, 133 | { 134 | "idiom" : "ipad", 135 | "size" : "83.5x83.5", 136 | "scale" : "2x" 137 | }, 138 | { 139 | "idiom" : "ios-marketing", 140 | "size" : "1024x1024", 141 | "scale" : "1x" 142 | }, 143 | { 144 | "size" : "60x60", 145 | "idiom" : "car", 146 | "filename" : "Icon-60@2x.png", 147 | "scale" : "2x" 148 | }, 149 | { 150 | "size" : "60x60", 151 | "idiom" : "car", 152 | "filename" : "Icon-60@3x.png", 153 | "scale" : "3x" 154 | }, 155 | { 156 | "size" : "24x24", 157 | "idiom" : "watch", 158 | "scale" : "2x", 159 | "role" : "notificationCenter", 160 | "subtype" : "38mm" 161 | }, 162 | { 163 | "size" : "27.5x27.5", 164 | "idiom" : "watch", 165 | "scale" : "2x", 166 | "role" : "notificationCenter", 167 | "subtype" : "42mm" 168 | }, 169 | { 170 | "size" : "29x29", 171 | "idiom" : "watch", 172 | "filename" : "Icon-Small@2x.png", 173 | "role" : "companionSettings", 174 | "scale" : "2x" 175 | }, 176 | { 177 | "size" : "29x29", 178 | "idiom" : "watch", 179 | "filename" : "Icon-Small@3x.png", 180 | "role" : "companionSettings", 181 | "scale" : "3x" 182 | }, 183 | { 184 | "size" : "40x40", 185 | "idiom" : "watch", 186 | "scale" : "2x", 187 | "role" : "appLauncher", 188 | "subtype" : "38mm" 189 | }, 190 | { 191 | "size" : "44x44", 192 | "idiom" : "watch", 193 | "scale" : "2x", 194 | "role" : "appLauncher", 195 | "subtype" : "40mm" 196 | }, 197 | { 198 | "size" : "50x50", 199 | "idiom" : "watch", 200 | "scale" : "2x", 201 | "role" : "appLauncher", 202 | "subtype" : "44mm" 203 | }, 204 | { 205 | "size" : "86x86", 206 | "idiom" : "watch", 207 | "scale" : "2x", 208 | "role" : "quickLook", 209 | "subtype" : "38mm" 210 | }, 211 | { 212 | "size" : "98x98", 213 | "idiom" : "watch", 214 | "scale" : "2x", 215 | "role" : "quickLook", 216 | "subtype" : "42mm" 217 | }, 218 | { 219 | "size" : "108x108", 220 | "idiom" : "watch", 221 | "scale" : "2x", 222 | "role" : "quickLook", 223 | "subtype" : "44mm" 224 | }, 225 | { 226 | "idiom" : "watch-marketing", 227 | "size" : "1024x1024", 228 | "scale" : "1x" 229 | }, 230 | { 231 | "idiom" : "mac", 232 | "size" : "16x16", 233 | "scale" : "1x" 234 | }, 235 | { 236 | "idiom" : "mac", 237 | "size" : "16x16", 238 | "scale" : "2x" 239 | }, 240 | { 241 | "idiom" : "mac", 242 | "size" : "32x32", 243 | "scale" : "1x" 244 | }, 245 | { 246 | "idiom" : "mac", 247 | "size" : "32x32", 248 | "scale" : "2x" 249 | }, 250 | { 251 | "idiom" : "mac", 252 | "size" : "128x128", 253 | "scale" : "1x" 254 | }, 255 | { 256 | "idiom" : "mac", 257 | "size" : "128x128", 258 | "scale" : "2x" 259 | }, 260 | { 261 | "idiom" : "mac", 262 | "size" : "256x256", 263 | "scale" : "1x" 264 | }, 265 | { 266 | "idiom" : "mac", 267 | "size" : "256x256", 268 | "scale" : "2x" 269 | }, 270 | { 271 | "idiom" : "mac", 272 | "size" : "512x512", 273 | "scale" : "1x" 274 | }, 275 | { 276 | "size" : "512x512", 277 | "idiom" : "mac", 278 | "filename" : "iTunesArtwork@2x.png", 279 | "scale" : "2x" 280 | } 281 | ], 282 | "info" : { 283 | "version" : 1, 284 | "author" : "xcode" 285 | } 286 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@2x-1.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@3x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@3x-1.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-72.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-40.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/samurai.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "samurai@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/samurai.imageset/samurai@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/samurai.imageset/samurai@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/samurai2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "samurai2@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/samurai2.imageset/samurai2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/samurai2.imageset/samurai2@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/splash_samurai.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "splash_samurai.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "splash_samurai@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "splash_samurai@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/splash_samurai.imageset/splash_samurai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/splash_samurai.imageset/splash_samurai.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/splash_samurai.imageset/splash_samurai@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/splash_samurai.imageset/splash_samurai@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/splash_samurai.imageset/splash_samurai@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hachinobu/SamuraiTransition/8ed87df2f54c0a5ba83c60b05331d91d567d480d/Example/Example/Assets.xcassets/splash_samurai.imageset/splash_samurai@3x.png -------------------------------------------------------------------------------- /Example/Example/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/Example/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | HelveticaNeue 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 52 | 60 | 68 | 76 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 111 | 121 | 130 | 139 | 147 | 155 | 163 | 171 | 179 | 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 | -------------------------------------------------------------------------------- /Example/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Example/Example/ModalViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ModalViewController.swift 3 | // Example 4 | // 5 | // Created by Takahiro Nishinobu on 2016/11/26. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SamuraiTransition 11 | 12 | class ModalViewController: SamuraiViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Example/Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Example 4 | // 5 | // Created by Takahiro Nishinobu on 2016/11/26. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SamuraiTransition 11 | 12 | class ViewController: UIViewController { 13 | 14 | @IBOutlet weak var zanSliderX: UISlider! 15 | @IBOutlet weak var zanSliderY: UISlider! 16 | @IBOutlet weak var zanLabelX: UILabel! 17 | @IBOutlet weak var zanLabelY: UILabel! 18 | var zanPoint: CGPoint! 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | title = "Samurai Transition" 23 | setupUI() 24 | } 25 | 26 | override func didReceiveMemoryWarning() { 27 | super.didReceiveMemoryWarning() 28 | // Dispose of any resources that can be recreated. 29 | } 30 | 31 | private func setupUI() { 32 | 33 | zanSliderX.minimumValue = 0.0 34 | zanSliderX.maximumValue = Float(view.frame.maxX) 35 | zanSliderX.setValue(Float(view.frame.midX), animated: true) 36 | zanSliderX.addTarget(self, action: #selector(changeSliderXValue(sender:)), for: .valueChanged) 37 | zanLabelX.text = zanSliderX.value.description 38 | 39 | zanSliderY.minimumValue = 0.0 40 | zanSliderY.maximumValue = Float(view.frame.maxY) 41 | zanSliderY.setValue(Float(view.frame.midY), animated: true) 42 | zanSliderY.addTarget(self, action: #selector(changeSliderYValue(sender:)), for: .valueChanged) 43 | zanLabelY.text = zanSliderY.value.description 44 | 45 | zanPoint = view.center 46 | } 47 | 48 | @objc func changeSliderXValue(sender: UISlider) { 49 | zanLabelX.text = sender.value.description 50 | zanPoint.x = CGFloat(sender.value) 51 | } 52 | 53 | @objc func changeSliderYValue(sender: UISlider) { 54 | zanLabelY.text = sender.value.description 55 | zanPoint.y = CGFloat(sender.value) 56 | } 57 | 58 | @IBAction func horizontalZan(_ sender: Any) { 59 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 60 | navigationController?.delegate = vc.samuraiTransition 61 | vc.samuraiTransition.zan = .horizontal 62 | vc.samuraiTransition.zanPoint = zanPoint 63 | navigationController?.pushViewController(vc, animated: true) 64 | // navigationController?.present(vc, animated: true, completion: nil) 65 | } 66 | 67 | @IBAction func verticalZan(_ sender: Any) { 68 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 69 | vc.samuraiTransition.zan = .vertical 70 | vc.samuraiTransition.zanPoint = zanPoint 71 | present(vc, animated: true, completion: nil) 72 | } 73 | 74 | @IBAction func diagonallyZan(_ sender: Any) { 75 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 76 | vc.samuraiTransition.zan = .diagonally 77 | vc.samuraiTransition.zanPoint = zanPoint 78 | present(vc, animated: true, completion: nil) 79 | } 80 | 81 | @IBAction func crossZan(_ sender: Any) { 82 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 83 | vc.samuraiTransition.zan = .cross 84 | vc.samuraiTransition.zanPoint = zanPoint 85 | present(vc, animated: true, completion: nil) 86 | } 87 | 88 | @IBAction func xZan(_ sender: Any) { 89 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 90 | vc.samuraiTransition.zan = .x 91 | vc.samuraiTransition.zanPoint = zanPoint 92 | present(vc, animated: true, completion: nil) 93 | } 94 | 95 | @IBAction func jaggedZan(_ sender: Any) { 96 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 97 | vc.samuraiTransition.zan = .jagged(width: 5.0) 98 | vc.samuraiTransition.zanPoint = zanPoint 99 | present(vc, animated: true, completion: nil) 100 | } 101 | 102 | @IBAction func circleZan(_ sender: Any) { 103 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 104 | vc.samuraiTransition.zan = .circle(radius: 50.0) 105 | vc.samuraiTransition.zanPoint = zanPoint 106 | present(vc, animated: true, completion: nil) 107 | } 108 | 109 | @IBAction func rectangleZan(_ sender: Any) { 110 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 111 | vc.samuraiTransition.zan = .rectangle(width: 100.0, height: 100.0, cornerRadius: 5.0) 112 | vc.samuraiTransition.zanPoint = zanPoint 113 | present(vc, animated: true, completion: nil) 114 | } 115 | 116 | @IBAction func triangleZan(_ sender: Any) { 117 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 118 | vc.samuraiTransition.zan = .triangle(oneSide: 200.0) 119 | vc.samuraiTransition.zanPoint = zanPoint 120 | present(vc, animated: true, completion: nil) 121 | } 122 | 123 | @IBAction func shreddedZan(_ sender: Any) { 124 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 125 | navigationController?.delegate = vc.samuraiTransition 126 | vc.samuraiTransition.zan = .shredded(isHorizontal: true, shreddedCount: 50) 127 | present(vc, animated: true) 128 | } 129 | 130 | @IBAction func choppedZan(_ sender: Any) { 131 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 132 | vc.samuraiTransition.zan = .chopped(oneSide: 20.0) 133 | vc.samuraiTransition.isAffineTransform = false 134 | present(vc, animated: true) 135 | } 136 | 137 | 138 | 139 | } 140 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Takahiro Nishinobu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![SamuraiTransition](https://cloud.githubusercontent.com/assets/1317847/21515399/a0b30e80-cd12-11e6-9170-fb61c0143c17.png) 2 | 3 | 4 | SamuraiTransiton is a ViewController transition framework in Swift. 5 | 6 | It is an animation as if Samurai cut out the screen with a sword. 7 | 8 | # transition types 9 | 10 | |horizontal|vertical|diaonally|cross| 11 | |:--:|:--:|:--:|:--:| 12 | |![horizontalzan](https://user-images.githubusercontent.com/1317847/59350691-ad428600-8d57-11e9-80c5-3099d0d50cad.gif)|![vertical](https://user-images.githubusercontent.com/1317847/59350728-ccd9ae80-8d57-11e9-9290-ab0a7ec39a09.gif)|![diagonally](https://user-images.githubusercontent.com/1317847/59350753-dc58f780-8d57-11e9-932f-8a364288ba9b.gif)|![cross](https://user-images.githubusercontent.com/1317847/59350768-e2e76f00-8d57-11e9-95c1-561a4b1c0d3c.gif)| 13 | 14 | |x|jagged|circle|rectangle| 15 | |:--:|:--:|:--:|:--:| 16 | |![x](https://user-images.githubusercontent.com/1317847/59350778-e8dd5000-8d57-11e9-892d-8b3fd7908436.gif)|![jagged](https://user-images.githubusercontent.com/1317847/59350777-e8dd5000-8d57-11e9-87f5-76f80acc134b.gif)|![circle](https://user-images.githubusercontent.com/1317847/59350779-e8dd5000-8d57-11e9-8e02-c73906579d2d.gif)|![rectangle](https://user-images.githubusercontent.com/1317847/59350780-e8dd5000-8d57-11e9-9433-c971529bac8e.gif)| 17 | 18 | |triangle|shredded|chopped| 19 | |:--:|:--:|:--:| 20 | |![triangle](https://user-images.githubusercontent.com/1317847/59350781-e975e680-8d57-11e9-8e0e-0d44641d878c.gif)|![shredded](https://user-images.githubusercontent.com/1317847/59350792-eda20400-8d57-11e9-9fa1-630793735446.gif)|![chopped](https://user-images.githubusercontent.com/1317847/59350795-eda20400-8d57-11e9-9a2a-a69113f8324f.gif)| 21 | 22 | 23 | 24 | 25 | # Usage 26 | ### Simple 27 | 28 | ```swift 29 | 30 | // make your view controller a subclass of SamuraiViewController 31 | // present it as normal 32 | 33 | import SamuraiTransition 34 | 35 | class ModalViewController: SamuraiViewController { 36 | //... 37 | } 38 | 39 | class ViewController: UIViewController { 40 | 41 | @IBAction func horizontalZan(_ sender: Any) { 42 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 43 | present(vc, animated: true, completion: nil) 44 | } 45 | 46 | @IBAction func verticalZan(_ sender: Any) { 47 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 48 | // customization 49 | vc.samuraiTransition.zan = .vertical 50 | present(vc, animated: true, completion: nil) 51 | } 52 | 53 | @IBAction func diagonallyZan(_ sender: Any) { 54 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 55 | // customization 56 | vc.samuraiTransition.zan = .diagonally 57 | present(vc, animated: true, completion: nil) 58 | } 59 | 60 | } 61 | 62 | ``` 63 | 64 | ### Attributes you can set 65 | 66 | ```swift 67 | //Time of transition 68 | public var duration: TimeInterval = 0.33 69 | //presenting or not 70 | public var presenting = true 71 | //horizontal or vertical or diagonally 72 | public var zan = Zan.horizontal 73 | //enable or disable affine processing when ModalViewcontroller appears 74 | public var isAffineTransform: Bool = true 75 | //Passing point of the sword line 76 | public var zanPoint: CGPoint? 77 | //sword line color 78 | public var zanLineColor = UIColor.black 79 | //sword line width 80 | public var zanLineWidth: CGFloat = 1.0 81 | 82 | ``` 83 | 84 | ### Custom 85 | 86 | ```swift 87 | 88 | class ViewController: UIViewController { 89 | 90 | let transition = SamuraiTransition() 91 | 92 | override func viewDidLoad() { 93 | super.viewDidLoad() 94 | transition.duration = 1.0 95 | transition.zan = Zan.vertical 96 | transition.isAffineTransform = false 97 | transition.zanLineColor = .blue 98 | transition.zanLineWidth = 2.0 99 | } 100 | 101 | @IBAction func tapModalButton(_ sender: AnyObject) { 102 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 103 | let button = sender as! UIButton 104 | transition.zanPoint = CGPoint(x: button.center.x, y: button.center.y) 105 | // vc.transitioningDelegate = transition 106 | vc.transitioningDelegate = self 107 | present(vc, animated: true, completion: nil) 108 | } 109 | 110 | } 111 | 112 | extension ViewController: UIViewControllerTransitioningDelegate { 113 | 114 | func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 115 | transition.presenting = true 116 | return transition 117 | } 118 | 119 | func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 120 | transition.presenting = false 121 | return transition 122 | } 123 | 124 | } 125 | 126 | 127 | ``` 128 | 129 | # Requirements 130 | * Xcode 10 or higher 131 | * iOS 9.0 or higher 132 | * Swift 5.0 133 | 134 | # Installation 135 | #### [CocoaPods](https://github.com/cocoapods/cocoapods) 136 | 137 | `pod 'SamuraiTransition'` 138 | 139 | #### [Carthage](https://github.com/Carthage/Carthage) 140 | 141 | - Insert `github "hachinobu/SamuraiTransition"` 142 | - Run `carthage update`. 143 | - Link your app with `SamuraiTransition.framework` in `Carthage/Build`. 144 | 145 | # License 146 | SamuraiTransiton is available under the MIT license. See the LICENSE file for more info. 147 | -------------------------------------------------------------------------------- /SamuraiTransition.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "SamuraiTransition" 4 | s.version = "1.1.0" 5 | s.summary = "SamuraiTransiton is a ViewController transition framework in Swift." 6 | s.homepage = "https://github.com/hachinobu/SamuraiTransition" 7 | 8 | 9 | s.license = "MIT" 10 | s.author = { "Takahiro Nishinobu" => "hachinobu@gmail.com" } 11 | s.source = { :git => "https://github.com/hachinobu/SamuraiTransition.git", :tag => s.version } 12 | 13 | s.ios.deployment_target = "9.0" 14 | 15 | s.source_files = "SamuraiTransition/**/*.swift" 16 | s.swift_version = "5.0" 17 | 18 | end 19 | -------------------------------------------------------------------------------- /SamuraiTransition.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AD5B398C1E0438F2004C56A2 /* CircleZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD5B398B1E0438F2004C56A2 /* CircleZanConfig.swift */; }; 11 | AD5B39901E06C341004C56A2 /* RectangleZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD5B398F1E06C341004C56A2 /* RectangleZanConfig.swift */; }; 12 | AD8D82471E4E0247006E26E4 /* ChoppedZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD8D82461E4E0247006E26E4 /* ChoppedZanConfig.swift */; }; 13 | ADDC02641DFD332A009EEC45 /* CrossZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADDC02631DFD332A009EEC45 /* CrossZanConfig.swift */; }; 14 | C2576BFF1E111EC9003572C2 /* ShreddedZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2576BFE1E111EC9003572C2 /* ShreddedZanConfig.swift */; }; 15 | C27839E71DF58ECF004B1E0C /* ZanViewConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C27839E61DF58ECF004B1E0C /* ZanViewConfig.swift */; }; 16 | C2892D891DFEAE5C007FE39E /* XZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2892D881DFEAE5C007FE39E /* XZanConfig.swift */; }; 17 | C29236721E03D4AD00A04FEE /* JaggedZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C29236711E03D4AD00A04FEE /* JaggedZanConfig.swift */; }; 18 | C29236751E07F80D00A04FEE /* TriangleZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C29236741E07F80D00A04FEE /* TriangleZanConfig.swift */; }; 19 | C2E5F6DE1DF806A30012CFE2 /* ZanViewConfigProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2E5F6DD1DF806A30012CFE2 /* ZanViewConfigProtocol.swift */; }; 20 | C2E5F6E01DF80D730012CFE2 /* SamuraiConfigProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2E5F6DF1DF80D730012CFE2 /* SamuraiConfigProtocol.swift */; }; 21 | C2E5F6E61DF8239F0012CFE2 /* ZanLineProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2E5F6E51DF8239F0012CFE2 /* ZanLineProtocol.swift */; }; 22 | C2E5F6E81DF825310012CFE2 /* VerticalZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2E5F6E71DF825310012CFE2 /* VerticalZanConfig.swift */; }; 23 | C2E5F6EA1DF828830012CFE2 /* DiagonallyZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2E5F6E91DF828830012CFE2 /* DiagonallyZanConfig.swift */; }; 24 | C2E5F6EC1DF82AC40012CFE2 /* HorizontalZanConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2E5F6EB1DF82AC40012CFE2 /* HorizontalZanConfig.swift */; }; 25 | C2F716561DE9565000480CAB /* SamuraiTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = C2F716541DE9565000480CAB /* SamuraiTransition.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26 | C2F716861DE959FF00480CAB /* Zan.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F716851DE959FF00480CAB /* Zan.swift */; }; 27 | C2F716881DE95ABC00480CAB /* SamuraiTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F716871DE95ABC00480CAB /* SamuraiTransition.swift */; }; 28 | C2F716921DF2665C00480CAB /* SamuraiViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F716911DF2665C00480CAB /* SamuraiViewController.swift */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | AD5B398B1E0438F2004C56A2 /* CircleZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircleZanConfig.swift; sourceTree = ""; }; 33 | AD5B398F1E06C341004C56A2 /* RectangleZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RectangleZanConfig.swift; sourceTree = ""; }; 34 | AD8D82461E4E0247006E26E4 /* ChoppedZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChoppedZanConfig.swift; sourceTree = ""; }; 35 | ADDC02631DFD332A009EEC45 /* CrossZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CrossZanConfig.swift; sourceTree = ""; }; 36 | C2576BFE1E111EC9003572C2 /* ShreddedZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShreddedZanConfig.swift; sourceTree = ""; }; 37 | C27839E61DF58ECF004B1E0C /* ZanViewConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZanViewConfig.swift; sourceTree = ""; }; 38 | C2892D881DFEAE5C007FE39E /* XZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XZanConfig.swift; sourceTree = ""; }; 39 | C29236711E03D4AD00A04FEE /* JaggedZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JaggedZanConfig.swift; sourceTree = ""; }; 40 | C29236741E07F80D00A04FEE /* TriangleZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TriangleZanConfig.swift; sourceTree = ""; }; 41 | C2E5F6DD1DF806A30012CFE2 /* ZanViewConfigProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZanViewConfigProtocol.swift; sourceTree = ""; }; 42 | C2E5F6DF1DF80D730012CFE2 /* SamuraiConfigProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SamuraiConfigProtocol.swift; sourceTree = ""; }; 43 | C2E5F6E51DF8239F0012CFE2 /* ZanLineProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZanLineProtocol.swift; sourceTree = ""; }; 44 | C2E5F6E71DF825310012CFE2 /* VerticalZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticalZanConfig.swift; sourceTree = ""; }; 45 | C2E5F6E91DF828830012CFE2 /* DiagonallyZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiagonallyZanConfig.swift; sourceTree = ""; }; 46 | C2E5F6EB1DF82AC40012CFE2 /* HorizontalZanConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HorizontalZanConfig.swift; sourceTree = ""; }; 47 | C2F716511DE9565000480CAB /* SamuraiTransition.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SamuraiTransition.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | C2F716541DE9565000480CAB /* SamuraiTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SamuraiTransition.h; sourceTree = ""; }; 49 | C2F716551DE9565000480CAB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | C2F716851DE959FF00480CAB /* Zan.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Zan.swift; sourceTree = ""; }; 51 | C2F716871DE95ABC00480CAB /* SamuraiTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SamuraiTransition.swift; sourceTree = ""; }; 52 | C2F716911DF2665C00480CAB /* SamuraiViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SamuraiViewController.swift; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | C2F7164D1DE9565000480CAB /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | C27158BD1F7A6BD60088144C /* ViewController */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | C2F716911DF2665C00480CAB /* SamuraiViewController.swift */, 70 | ); 71 | path = ViewController; 72 | sourceTree = ""; 73 | }; 74 | C27158BE1F7A6BED0088144C /* Zan */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | C27158BF1F7A6BFA0088144C /* Config */, 78 | C2F716851DE959FF00480CAB /* Zan.swift */, 79 | ); 80 | path = Zan; 81 | sourceTree = ""; 82 | }; 83 | C27158BF1F7A6BFA0088144C /* Config */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | C2E5F6E51DF8239F0012CFE2 /* ZanLineProtocol.swift */, 87 | C2E5F6EB1DF82AC40012CFE2 /* HorizontalZanConfig.swift */, 88 | C2E5F6E71DF825310012CFE2 /* VerticalZanConfig.swift */, 89 | C2E5F6E91DF828830012CFE2 /* DiagonallyZanConfig.swift */, 90 | ADDC02631DFD332A009EEC45 /* CrossZanConfig.swift */, 91 | C2892D881DFEAE5C007FE39E /* XZanConfig.swift */, 92 | C29236711E03D4AD00A04FEE /* JaggedZanConfig.swift */, 93 | AD5B398B1E0438F2004C56A2 /* CircleZanConfig.swift */, 94 | AD5B398F1E06C341004C56A2 /* RectangleZanConfig.swift */, 95 | C29236741E07F80D00A04FEE /* TriangleZanConfig.swift */, 96 | C2576BFE1E111EC9003572C2 /* ShreddedZanConfig.swift */, 97 | AD8D82461E4E0247006E26E4 /* ChoppedZanConfig.swift */, 98 | C27839E61DF58ECF004B1E0C /* ZanViewConfig.swift */, 99 | C2E5F6DD1DF806A30012CFE2 /* ZanViewConfigProtocol.swift */, 100 | C2E5F6DF1DF80D730012CFE2 /* SamuraiConfigProtocol.swift */, 101 | ); 102 | path = Config; 103 | sourceTree = ""; 104 | }; 105 | C2F716471DE9565000480CAB = { 106 | isa = PBXGroup; 107 | children = ( 108 | C2F716531DE9565000480CAB /* SamuraiTransition */, 109 | C2F716521DE9565000480CAB /* Products */, 110 | ); 111 | sourceTree = ""; 112 | }; 113 | C2F716521DE9565000480CAB /* Products */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | C2F716511DE9565000480CAB /* SamuraiTransition.framework */, 117 | ); 118 | name = Products; 119 | sourceTree = ""; 120 | }; 121 | C2F716531DE9565000480CAB /* SamuraiTransition */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | C2F716871DE95ABC00480CAB /* SamuraiTransition.swift */, 125 | C27158BE1F7A6BED0088144C /* Zan */, 126 | C27158BD1F7A6BD60088144C /* ViewController */, 127 | C2F716541DE9565000480CAB /* SamuraiTransition.h */, 128 | C2F716551DE9565000480CAB /* Info.plist */, 129 | ); 130 | path = SamuraiTransition; 131 | sourceTree = ""; 132 | }; 133 | /* End PBXGroup section */ 134 | 135 | /* Begin PBXHeadersBuildPhase section */ 136 | C2F7164E1DE9565000480CAB /* Headers */ = { 137 | isa = PBXHeadersBuildPhase; 138 | buildActionMask = 2147483647; 139 | files = ( 140 | C2F716561DE9565000480CAB /* SamuraiTransition.h in Headers */, 141 | ); 142 | runOnlyForDeploymentPostprocessing = 0; 143 | }; 144 | /* End PBXHeadersBuildPhase section */ 145 | 146 | /* Begin PBXNativeTarget section */ 147 | C2F716501DE9565000480CAB /* SamuraiTransition */ = { 148 | isa = PBXNativeTarget; 149 | buildConfigurationList = C2F716591DE9565000480CAB /* Build configuration list for PBXNativeTarget "SamuraiTransition" */; 150 | buildPhases = ( 151 | C2F7164C1DE9565000480CAB /* Sources */, 152 | C2F7164D1DE9565000480CAB /* Frameworks */, 153 | C2F7164E1DE9565000480CAB /* Headers */, 154 | C2F7164F1DE9565000480CAB /* Resources */, 155 | ); 156 | buildRules = ( 157 | ); 158 | dependencies = ( 159 | ); 160 | name = SamuraiTransition; 161 | productName = SamuraiTransition; 162 | productReference = C2F716511DE9565000480CAB /* SamuraiTransition.framework */; 163 | productType = "com.apple.product-type.framework"; 164 | }; 165 | /* End PBXNativeTarget section */ 166 | 167 | /* Begin PBXProject section */ 168 | C2F716481DE9565000480CAB /* Project object */ = { 169 | isa = PBXProject; 170 | attributes = { 171 | LastUpgradeCheck = 0940; 172 | ORGANIZATIONNAME = hachinobu; 173 | TargetAttributes = { 174 | C2F716501DE9565000480CAB = { 175 | CreatedOnToolsVersion = 8.1; 176 | LastSwiftMigration = 1020; 177 | ProvisioningStyle = Automatic; 178 | }; 179 | }; 180 | }; 181 | buildConfigurationList = C2F7164B1DE9565000480CAB /* Build configuration list for PBXProject "SamuraiTransition" */; 182 | compatibilityVersion = "Xcode 3.2"; 183 | developmentRegion = en; 184 | hasScannedForEncodings = 0; 185 | knownRegions = ( 186 | en, 187 | Base, 188 | ); 189 | mainGroup = C2F716471DE9565000480CAB; 190 | productRefGroup = C2F716521DE9565000480CAB /* Products */; 191 | projectDirPath = ""; 192 | projectRoot = ""; 193 | targets = ( 194 | C2F716501DE9565000480CAB /* SamuraiTransition */, 195 | ); 196 | }; 197 | /* End PBXProject section */ 198 | 199 | /* Begin PBXResourcesBuildPhase section */ 200 | C2F7164F1DE9565000480CAB /* Resources */ = { 201 | isa = PBXResourcesBuildPhase; 202 | buildActionMask = 2147483647; 203 | files = ( 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | /* End PBXResourcesBuildPhase section */ 208 | 209 | /* Begin PBXSourcesBuildPhase section */ 210 | C2F7164C1DE9565000480CAB /* Sources */ = { 211 | isa = PBXSourcesBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | C2F716861DE959FF00480CAB /* Zan.swift in Sources */, 215 | C2E5F6DE1DF806A30012CFE2 /* ZanViewConfigProtocol.swift in Sources */, 216 | AD5B398C1E0438F2004C56A2 /* CircleZanConfig.swift in Sources */, 217 | C29236751E07F80D00A04FEE /* TriangleZanConfig.swift in Sources */, 218 | C2E5F6EA1DF828830012CFE2 /* DiagonallyZanConfig.swift in Sources */, 219 | C2576BFF1E111EC9003572C2 /* ShreddedZanConfig.swift in Sources */, 220 | ADDC02641DFD332A009EEC45 /* CrossZanConfig.swift in Sources */, 221 | C2892D891DFEAE5C007FE39E /* XZanConfig.swift in Sources */, 222 | AD5B39901E06C341004C56A2 /* RectangleZanConfig.swift in Sources */, 223 | C2E5F6EC1DF82AC40012CFE2 /* HorizontalZanConfig.swift in Sources */, 224 | C2E5F6E61DF8239F0012CFE2 /* ZanLineProtocol.swift in Sources */, 225 | C2E5F6E81DF825310012CFE2 /* VerticalZanConfig.swift in Sources */, 226 | C2F716881DE95ABC00480CAB /* SamuraiTransition.swift in Sources */, 227 | C2F716921DF2665C00480CAB /* SamuraiViewController.swift in Sources */, 228 | C27839E71DF58ECF004B1E0C /* ZanViewConfig.swift in Sources */, 229 | C2E5F6E01DF80D730012CFE2 /* SamuraiConfigProtocol.swift in Sources */, 230 | C29236721E03D4AD00A04FEE /* JaggedZanConfig.swift in Sources */, 231 | AD8D82471E4E0247006E26E4 /* ChoppedZanConfig.swift in Sources */, 232 | ); 233 | runOnlyForDeploymentPostprocessing = 0; 234 | }; 235 | /* End PBXSourcesBuildPhase section */ 236 | 237 | /* Begin XCBuildConfiguration section */ 238 | C2F716571DE9565000480CAB /* Debug */ = { 239 | isa = XCBuildConfiguration; 240 | buildSettings = { 241 | ALWAYS_SEARCH_USER_PATHS = NO; 242 | CLANG_ANALYZER_NONNULL = YES; 243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 244 | CLANG_CXX_LIBRARY = "libc++"; 245 | CLANG_ENABLE_MODULES = YES; 246 | CLANG_ENABLE_OBJC_ARC = YES; 247 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 248 | CLANG_WARN_BOOL_CONVERSION = YES; 249 | CLANG_WARN_COMMA = YES; 250 | CLANG_WARN_CONSTANT_CONVERSION = YES; 251 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 252 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 253 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 254 | CLANG_WARN_EMPTY_BODY = YES; 255 | CLANG_WARN_ENUM_CONVERSION = YES; 256 | CLANG_WARN_INFINITE_RECURSION = YES; 257 | CLANG_WARN_INT_CONVERSION = YES; 258 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 259 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 260 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 261 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 262 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 263 | CLANG_WARN_STRICT_PROTOTYPES = YES; 264 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 265 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 266 | CLANG_WARN_UNREACHABLE_CODE = YES; 267 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 268 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 269 | COPY_PHASE_STRIP = NO; 270 | CURRENT_PROJECT_VERSION = 1; 271 | DEBUG_INFORMATION_FORMAT = dwarf; 272 | ENABLE_STRICT_OBJC_MSGSEND = YES; 273 | ENABLE_TESTABILITY = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu99; 275 | GCC_DYNAMIC_NO_PIC = NO; 276 | GCC_NO_COMMON_BLOCKS = YES; 277 | GCC_OPTIMIZATION_LEVEL = 0; 278 | GCC_PREPROCESSOR_DEFINITIONS = ( 279 | "DEBUG=1", 280 | "$(inherited)", 281 | ); 282 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 283 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 284 | GCC_WARN_UNDECLARED_SELECTOR = YES; 285 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 286 | GCC_WARN_UNUSED_FUNCTION = YES; 287 | GCC_WARN_UNUSED_VARIABLE = YES; 288 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 289 | MTL_ENABLE_DEBUG_INFO = YES; 290 | ONLY_ACTIVE_ARCH = YES; 291 | SDKROOT = iphoneos; 292 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 293 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 294 | SWIFT_VERSION = 4.0; 295 | TARGETED_DEVICE_FAMILY = "1,2"; 296 | VERSIONING_SYSTEM = "apple-generic"; 297 | VERSION_INFO_PREFIX = ""; 298 | }; 299 | name = Debug; 300 | }; 301 | C2F716581DE9565000480CAB /* Release */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ALWAYS_SEARCH_USER_PATHS = NO; 305 | CLANG_ANALYZER_NONNULL = YES; 306 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 307 | CLANG_CXX_LIBRARY = "libc++"; 308 | CLANG_ENABLE_MODULES = YES; 309 | CLANG_ENABLE_OBJC_ARC = YES; 310 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 311 | CLANG_WARN_BOOL_CONVERSION = YES; 312 | CLANG_WARN_COMMA = YES; 313 | CLANG_WARN_CONSTANT_CONVERSION = YES; 314 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 315 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 316 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 326 | CLANG_WARN_STRICT_PROTOTYPES = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 328 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 329 | CLANG_WARN_UNREACHABLE_CODE = YES; 330 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 331 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 332 | COPY_PHASE_STRIP = NO; 333 | CURRENT_PROJECT_VERSION = 1; 334 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 335 | ENABLE_NS_ASSERTIONS = NO; 336 | ENABLE_STRICT_OBJC_MSGSEND = YES; 337 | GCC_C_LANGUAGE_STANDARD = gnu99; 338 | GCC_NO_COMMON_BLOCKS = YES; 339 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 340 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 341 | GCC_WARN_UNDECLARED_SELECTOR = YES; 342 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 343 | GCC_WARN_UNUSED_FUNCTION = YES; 344 | GCC_WARN_UNUSED_VARIABLE = YES; 345 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 346 | MTL_ENABLE_DEBUG_INFO = NO; 347 | SDKROOT = iphoneos; 348 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 349 | SWIFT_VERSION = 4.0; 350 | TARGETED_DEVICE_FAMILY = "1,2"; 351 | VALIDATE_PRODUCT = YES; 352 | VERSIONING_SYSTEM = "apple-generic"; 353 | VERSION_INFO_PREFIX = ""; 354 | }; 355 | name = Release; 356 | }; 357 | C2F7165A1DE9565000480CAB /* Debug */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | CLANG_ENABLE_MODULES = YES; 361 | CODE_SIGN_IDENTITY = ""; 362 | DEFINES_MODULE = YES; 363 | DYLIB_COMPATIBILITY_VERSION = 1; 364 | DYLIB_CURRENT_VERSION = 1; 365 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 366 | INFOPLIST_FILE = SamuraiTransition/Info.plist; 367 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 368 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 369 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 370 | PRODUCT_BUNDLE_IDENTIFIER = hachinobu.SamuraiTransition.SamuraiTransition; 371 | PRODUCT_NAME = "$(TARGET_NAME)"; 372 | SKIP_INSTALL = YES; 373 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 374 | SWIFT_VERSION = 5.0; 375 | }; 376 | name = Debug; 377 | }; 378 | C2F7165B1DE9565000480CAB /* Release */ = { 379 | isa = XCBuildConfiguration; 380 | buildSettings = { 381 | CLANG_ENABLE_MODULES = YES; 382 | CODE_SIGN_IDENTITY = ""; 383 | DEFINES_MODULE = YES; 384 | DYLIB_COMPATIBILITY_VERSION = 1; 385 | DYLIB_CURRENT_VERSION = 1; 386 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 387 | INFOPLIST_FILE = SamuraiTransition/Info.plist; 388 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 389 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 390 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 391 | PRODUCT_BUNDLE_IDENTIFIER = hachinobu.SamuraiTransition.SamuraiTransition; 392 | PRODUCT_NAME = "$(TARGET_NAME)"; 393 | SKIP_INSTALL = YES; 394 | SWIFT_VERSION = 5.0; 395 | }; 396 | name = Release; 397 | }; 398 | /* End XCBuildConfiguration section */ 399 | 400 | /* Begin XCConfigurationList section */ 401 | C2F7164B1DE9565000480CAB /* Build configuration list for PBXProject "SamuraiTransition" */ = { 402 | isa = XCConfigurationList; 403 | buildConfigurations = ( 404 | C2F716571DE9565000480CAB /* Debug */, 405 | C2F716581DE9565000480CAB /* Release */, 406 | ); 407 | defaultConfigurationIsVisible = 0; 408 | defaultConfigurationName = Release; 409 | }; 410 | C2F716591DE9565000480CAB /* Build configuration list for PBXNativeTarget "SamuraiTransition" */ = { 411 | isa = XCConfigurationList; 412 | buildConfigurations = ( 413 | C2F7165A1DE9565000480CAB /* Debug */, 414 | C2F7165B1DE9565000480CAB /* Release */, 415 | ); 416 | defaultConfigurationIsVisible = 0; 417 | defaultConfigurationName = Release; 418 | }; 419 | /* End XCConfigurationList section */ 420 | }; 421 | rootObject = C2F716481DE9565000480CAB /* Project object */; 422 | } 423 | -------------------------------------------------------------------------------- /SamuraiTransition.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SamuraiTransition.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SamuraiTransition.xcodeproj/xcshareddata/xcschemes/SamuraiTransition.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 | -------------------------------------------------------------------------------- /SamuraiTransition/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 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /SamuraiTransition/SamuraiTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // SamuraiTransition.h 3 | // SamuraiTransition 4 | // 5 | // Created by Takahiro Nishinobu on 2016/11/26. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SamuraiTransition. 12 | FOUNDATION_EXPORT double SamuraiTransitionVersionNumber; 13 | 14 | //! Project version string for SamuraiTransition. 15 | FOUNDATION_EXPORT const unsigned char SamuraiTransitionVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /SamuraiTransition/SamuraiTransition.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SamuraiTransition.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Takahiro Nishinobu on 2016/11/26. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class SamuraiTransition: NSObject { 12 | 13 | public var duration: TimeInterval = 0.33 14 | public var presenting = true 15 | public var zan = Zan.horizontal 16 | public var isAffineTransform: Bool = true 17 | public var zanPoint: CGPoint? 18 | public var zanLineColor = UIColor.black 19 | public var zanLineWidth: CGFloat = 1.0 20 | public var operation: UINavigationController.Operation! { 21 | didSet { 22 | popOperation = operation == .pop 23 | } 24 | } 25 | 26 | fileprivate var popOperation: Bool = false 27 | 28 | fileprivate weak var transitionContext: UIViewControllerContextTransitioning! 29 | fileprivate var containerView: UIView! 30 | 31 | fileprivate var containerFrame: CGRect { 32 | return containerView.frame 33 | } 34 | 35 | fileprivate var toViewController: UIViewController { 36 | return transitionContext.viewController(forKey: .to)! 37 | } 38 | 39 | fileprivate var toView: UIView { 40 | return transitionContext.view(forKey: .to)! 41 | } 42 | 43 | fileprivate var fromViewController: UIViewController { 44 | return transitionContext.viewController(forKey: .from)! 45 | } 46 | 47 | fileprivate var fromView: UIView { 48 | return transitionContext.view(forKey: .from)! 49 | } 50 | 51 | fileprivate let coverView: UIView = { 52 | let view = UIView() 53 | view.backgroundColor = .black 54 | return view 55 | }() 56 | 57 | fileprivate var zanLineDuration: TimeInterval { 58 | let zanDuration = duration - 0.16 59 | if zanDuration > 0.0 { 60 | return 0.16 61 | } 62 | return 0.0 63 | } 64 | 65 | } 66 | 67 | extension SamuraiTransition: UIViewControllerAnimatedTransitioning { 68 | 69 | public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 70 | return duration 71 | } 72 | 73 | public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 74 | 75 | self.transitionContext = transitionContext 76 | containerView = transitionContext.containerView 77 | 78 | coverView.frame = containerFrame 79 | containerView.addSubview(coverView) 80 | 81 | let point = zanPoint ?? containerView.center 82 | let samuraiConfig = zan.samuraiConfig(containerFrame: containerFrame, zanPoint: point, lineWidth: zanLineWidth, lineColor: zanLineColor) 83 | 84 | if presenting { 85 | 86 | containerView.addSubview(toView) 87 | 88 | let zanViews: [UIView] = samuraiConfig.zanViewConfigList.map { 89 | return fromView.resizableSnapshotView(from: $0.inSideFrame, afterScreenUpdates: false, withCapInsets: .zero)! 90 | } 91 | 92 | zip(zanViews, samuraiConfig.zanViewConfigList).forEach { (view, config) in 93 | containerView.addSubview(view) 94 | view.frame = config.viewFrame(isPresenting: presenting) 95 | view.layer.mask = config.mask 96 | view.transform = CGAffineTransform.identity 97 | } 98 | 99 | toView.alpha = 0.0 100 | if isAffineTransform { 101 | toView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5) 102 | } 103 | 104 | CATransaction.begin() 105 | CATransaction.setCompletionBlock { 106 | samuraiConfig.lineLayers.forEach { $0.removeFromSuperlayer() } 107 | UIView.animate(withDuration: self.duration - self.zanLineDuration, animations: { 108 | 109 | zip(zanViews, samuraiConfig.zanViewConfigList).forEach { (view, config) in 110 | view.frame = config.outSideFrame 111 | view.alpha = config.isAlphaAnimation ? 0.0 : 1.0 112 | if config.isScaleAnimation { 113 | view.transform = CGAffineTransform(scaleX: 0.1, y: 0.1) 114 | } 115 | } 116 | self.toView.alpha = 1.0 117 | self.toView.transform = CGAffineTransform.identity 118 | 119 | }, completion: { _ in 120 | 121 | zanViews.forEach { $0.removeFromSuperview() } 122 | self.coverView.removeFromSuperview() 123 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 124 | 125 | }) 126 | } 127 | 128 | samuraiConfig.lineLayers.forEach { lineLayer in 129 | containerView.layer.addSublayer(lineLayer) 130 | let animation = lineLayerAnimation() 131 | lineLayer.add(animation, forKey: nil) 132 | } 133 | 134 | CATransaction.commit() 135 | 136 | } else { 137 | 138 | containerView.bringSubviewToFront(fromView) 139 | containerView.addSubview(toView) 140 | 141 | let zanViews: [UIView] = samuraiConfig.zanViewConfigList.map { 142 | return toView.resizableSnapshotView(from: $0.inSideFrame, afterScreenUpdates: !popOperation, withCapInsets: .zero)! 143 | } 144 | 145 | zip(zanViews, samuraiConfig.zanViewConfigList).forEach { (view, config) in 146 | containerView.addSubview(view) 147 | view.frame = config.viewFrame(isPresenting: presenting) 148 | view.layer.mask = config.mask 149 | if config.isScaleAnimation { 150 | view.transform = CGAffineTransform(scaleX: 0.1, y: 0.1) 151 | } 152 | } 153 | 154 | toView.isHidden = true 155 | UIView.animate(withDuration: duration, animations: { 156 | 157 | self.fromView.alpha = 0.0 158 | if self.isAffineTransform { 159 | self.fromView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5) 160 | } 161 | zip(zanViews, samuraiConfig.zanViewConfigList).forEach { $0.0.frame = $0.1.inSideFrame } 162 | 163 | }, completion: { _ in 164 | 165 | self.toView.isHidden = false 166 | self.fromView.removeFromSuperview() 167 | self.coverView.removeFromSuperview() 168 | zanViews.forEach { $0.removeFromSuperview() } 169 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 170 | 171 | }) 172 | 173 | } 174 | 175 | } 176 | 177 | } 178 | 179 | extension SamuraiTransition { 180 | 181 | fileprivate func lineLayerAnimation() -> CABasicAnimation { 182 | 183 | let lineAnimation = CABasicAnimation(keyPath: "strokeEnd") 184 | lineAnimation.duration = zanLineDuration 185 | lineAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn) 186 | lineAnimation.fromValue = 0.0 187 | lineAnimation.toValue = 1.0 188 | lineAnimation.fillMode = CAMediaTimingFillMode.forwards 189 | lineAnimation.isRemovedOnCompletion = false 190 | 191 | return lineAnimation 192 | } 193 | 194 | } 195 | 196 | extension SamuraiTransition: UIViewControllerTransitioningDelegate { 197 | 198 | public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 199 | self.presenting = true 200 | return self 201 | } 202 | 203 | public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 204 | self.presenting = false 205 | return self 206 | } 207 | 208 | } 209 | 210 | extension SamuraiTransition: UINavigationControllerDelegate { 211 | 212 | public func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { 213 | self.presenting = operation == .push 214 | self.operation = operation 215 | return self 216 | } 217 | 218 | } 219 | -------------------------------------------------------------------------------- /SamuraiTransition/ViewController/SamuraiViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SamuraiViewController.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Takahiro Nishinobu on 2016/12/03. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class SamuraiViewController: UIViewController { 12 | 13 | public lazy var samuraiTransition: SamuraiTransition = { 14 | let transition = SamuraiTransition() 15 | transition.duration = 0.33 16 | transition.isAffineTransform = true 17 | transition.zan = .horizontal 18 | transition.zanLineColor = .black 19 | return transition 20 | }() 21 | 22 | override public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 23 | super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 24 | commonInit() 25 | } 26 | 27 | required public init?(coder aDecoder: NSCoder) { 28 | super.init(coder: aDecoder) 29 | commonInit() 30 | } 31 | 32 | private func commonInit() { 33 | transitioningDelegate = samuraiTransition 34 | } 35 | 36 | open override func viewDidLoad() { 37 | super.viewDidLoad() 38 | setupDismissView() 39 | } 40 | 41 | open func setupDismissView() { 42 | 43 | let dismissView = UIView() 44 | dismissView.translatesAutoresizingMaskIntoConstraints = false 45 | dismissView.backgroundColor = .clear 46 | view.insertSubview(dismissView, at: 0) 47 | view.addConstraints([NSLayoutConstraint.Attribute.top, .left, .right, .bottom].map { 48 | NSLayoutConstraint(item: dismissView, attribute: $0, relatedBy: .equal, toItem: view, attribute: $0, multiplier: 1.0, constant: 0.0) 49 | }) 50 | 51 | let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapDismissView)) 52 | dismissView.addGestureRecognizer(tapRecognizer) 53 | } 54 | 55 | @objc open func tapDismissView() { 56 | dismiss(animated: true, completion: nil) 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/ChoppedZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChoppedZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Takahiro Nishinobu on 2017/02/10. 6 | // Copyright © 2017年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class ChoppedZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | let oneSide: CGFloat 18 | 19 | private let minimumOneSide: CGFloat = 3.0 20 | 21 | lazy var lineLayers: [CAShapeLayer] = { 22 | return self.choppedLineLayers() 23 | }() 24 | 25 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 26 | return self.zanViewConfigs() 27 | }() 28 | 29 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor, oneSide: CGFloat) { 30 | self.containerFrame = containerFrame 31 | self.zanPoint = zanPoint 32 | self.lineWidth = lineWidth 33 | self.lineColor = lineColor 34 | self.oneSide = oneSide > minimumOneSide ? oneSide : minimumOneSide 35 | } 36 | 37 | } 38 | 39 | extension ChoppedZanConfig { 40 | 41 | fileprivate func choppedLineLayers() -> [CAShapeLayer] { 42 | 43 | var lineLayers: [CAShapeLayer] = [] 44 | var isBreakLoop: (horizontal: Bool, vertical: Bool) = (false, false) 45 | 46 | for i in (1...Int.max) { 47 | 48 | let position = oneSide * CGFloat(i) 49 | isBreakLoop.horizontal = position > containerFrame.maxX 50 | isBreakLoop.vertical = position > containerFrame.maxY 51 | if isBreakLoop.horizontal && isBreakLoop.vertical { 52 | break 53 | } 54 | 55 | let isEven: Bool = i % 2 == 0 56 | let yPositions: (start: CGFloat, end: CGFloat) = isEven ? 57 | (containerFrame.minY, containerFrame.maxY) : (containerFrame.maxY, containerFrame.minY) 58 | 59 | let verticalPath = UIBezierPath() 60 | verticalPath.move(to: CGPoint(x: position, y: yPositions.start)) 61 | verticalPath.addLine(to: CGPoint(x: position, y: yPositions.end)) 62 | let verticalLineLayer = zanLineLayer(from: verticalPath, width: lineWidth, color: lineColor) 63 | lineLayers.append(verticalLineLayer) 64 | 65 | let xPositions: (start: CGFloat, end: CGFloat) = isEven ? 66 | (containerFrame.minX, containerFrame.maxX) : (containerFrame.maxX, containerFrame.minX) 67 | 68 | let horizontalPath = UIBezierPath() 69 | horizontalPath.move(to: CGPoint(x: xPositions.start, y: position)) 70 | horizontalPath.addLine(to: CGPoint(x: xPositions.end, y: position)) 71 | let horizontalLineLayer = zanLineLayer(from: horizontalPath, width: lineWidth, color: lineColor) 72 | lineLayers.append(horizontalLineLayer) 73 | 74 | } 75 | 76 | return lineLayers 77 | 78 | } 79 | 80 | fileprivate func zanViewConfigs() -> [ZanViewConfigProtocol] { 81 | 82 | let zanSize: CGSize = CGSize(width: oneSide, height: oneSide) 83 | var zanConfigs: [ZanViewConfigProtocol] = [] 84 | 85 | for i in (0...Int.max) { 86 | 87 | let positionY = CGFloat(i) * oneSide 88 | 89 | for j in (0...Int.max) { 90 | 91 | let positionX = CGFloat(j) * oneSide 92 | let frame = CGRect(origin: CGPoint(x: positionX, y: positionY), size: zanSize) 93 | let zan = ZanViewConfig(inSideFrame: frame, outSideFrame: frame, isScaleAnimation: true) 94 | zanConfigs.append(zan) 95 | 96 | if frame.maxX >= containerFrame.maxX { 97 | break 98 | } 99 | 100 | } 101 | 102 | if (positionY + oneSide) >= containerFrame.maxY { 103 | break 104 | } 105 | 106 | } 107 | 108 | return zanConfigs 109 | 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/CircleZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CircleZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Takahiro Nishinobu on 2016/12/17. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class CircleZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | var radius: CGFloat 18 | 19 | //conform SamuraiConfigProtocol 20 | lazy var lineLayers: [CAShapeLayer] = { 21 | let path = self.circleAreaPath() 22 | let lineLayer = self.zanLineLayer(from: path, width: self.lineWidth, color: self.lineColor) 23 | return [lineLayer] 24 | }() 25 | 26 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 27 | let maskLayers = self.zanMaskLayers() 28 | let oneSideConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame.offsetBy(dx: 0.0, dy: self.containerFrame.maxY), isAlphaAnimation: true, mask: maskLayers.oneSide) 29 | let otherSideConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame, mask: maskLayers.otherSide) 30 | return [oneSideConfig, otherSideConfig] 31 | }() 32 | 33 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor, radius: CGFloat) { 34 | self.containerFrame = containerFrame 35 | self.zanPoint = zanPoint 36 | self.lineWidth = lineWidth 37 | self.lineColor = lineColor 38 | self.radius = abs(radius) 39 | } 40 | 41 | } 42 | 43 | extension CircleZanConfig { 44 | 45 | fileprivate func circleAreaPath() -> UIBezierPath { 46 | let path = UIBezierPath() 47 | let startAngle = -CGFloat(Double.pi/2) 48 | let endAngle = CGFloat(Double.pi) + CGFloat(Double.pi/2) 49 | path.addArc(withCenter: zanPoint, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true) 50 | return path 51 | } 52 | 53 | fileprivate func zanMaskLayers() -> (oneSide: CAShapeLayer, otherSide: CAShapeLayer) { 54 | 55 | let oneSide = CAShapeLayer() 56 | let outerCirclePath = circleAreaPath() 57 | outerCirclePath.addLine(to: CGPoint(x: outerCirclePath.currentPoint.x, y: containerFrame.minY)) 58 | outerCirclePath.addLine(to: CGPoint(x: containerFrame.minX, y: outerCirclePath.currentPoint.y)) 59 | outerCirclePath.addLine(to: CGPoint(x: outerCirclePath.currentPoint.x, y: containerFrame.maxY)) 60 | outerCirclePath.addLine(to: CGPoint(x: containerFrame.maxX, y: outerCirclePath.currentPoint.y)) 61 | outerCirclePath.addLine(to: CGPoint(x: outerCirclePath.currentPoint.x, y: containerFrame.minY)) 62 | outerCirclePath.addLine(to: CGPoint(x: containerFrame.minX, y: outerCirclePath.currentPoint.y)) 63 | oneSide.path = outerCirclePath.cgPath 64 | 65 | let otherSide = CAShapeLayer() 66 | let innerCirclePath = circleAreaPath() 67 | otherSide.path = innerCirclePath.cgPath 68 | 69 | return (oneSide, otherSide) 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/CrossZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CrossZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Takahiro Nishinobu on 2016/12/11. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class CrossZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | 18 | //conform SamuraiConfigProtocol 19 | lazy var lineLayers: [CAShapeLayer] = { 20 | let oneCrossLayer = self.zanLineLayer(from: CGPoint(x: self.zanPoint.x, y: self.containerFrame.minY), end: CGPoint(x: self.zanPoint.x, y: self.containerFrame.maxY), width: self.lineWidth, color: self.lineColor) 21 | let otherCrossLayer = self.zanLineLayer(from: CGPoint(x: self.containerFrame.minX, y: self.zanPoint.y), end: CGPoint(x: self.containerFrame.maxX, y: self.zanPoint.y), width: self.lineWidth, color: self.lineColor) 22 | return [oneCrossLayer, otherCrossLayer] 23 | }() 24 | 25 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 26 | 27 | let leftTopRect = CGRect(x: self.containerFrame.minX, y: self.containerFrame.minY, width: self.zanPoint.x, height: self.zanPoint.y) 28 | let rightTopRect = CGRect(x: leftTopRect.width, y: self.containerFrame.minY, width: self.containerFrame.width - leftTopRect.width, height: leftTopRect.height) 29 | let leftBottomRect = CGRect(x: leftTopRect.minX, y: leftTopRect.maxY, width: leftTopRect.width, height: self.containerFrame.height - leftTopRect.height) 30 | let rightBottomRect = CGRect(x: leftTopRect.maxX, y: rightTopRect.maxY, width: rightTopRect.width, height: leftBottomRect.height) 31 | 32 | let leftTopConfig = ZanViewConfig(inSideFrame: leftTopRect, outSideFrame: leftTopRect.offsetBy(dx: -leftTopRect.width, dy: -leftTopRect.height)) 33 | let rightTopConfig = ZanViewConfig(inSideFrame: rightTopRect, outSideFrame: rightTopRect.offsetBy(dx: rightTopRect.width, dy: -rightTopRect.height)) 34 | let leftBottomConfig = ZanViewConfig(inSideFrame: leftBottomRect, outSideFrame: leftBottomRect.offsetBy(dx: -leftBottomRect.width, dy: leftBottomRect.height)) 35 | let rightBottomConfig = ZanViewConfig(inSideFrame: rightBottomRect, outSideFrame: rightBottomRect.offsetBy(dx: rightBottomRect.width, dy: rightBottomRect.height)) 36 | 37 | return [leftTopConfig, rightTopConfig, leftBottomConfig, rightBottomConfig] 38 | }() 39 | 40 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor) { 41 | self.containerFrame = containerFrame 42 | self.zanPoint = zanPoint 43 | self.lineWidth = lineWidth 44 | self.lineColor = lineColor 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/DiagonallyZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DiagonallyZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/07. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class DiagonallyZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | 18 | //conform SamuraiConfigProtocol 19 | lazy var lineLayers: [CAShapeLayer] = { 20 | let lineLayer = self.zanLineLayer(from: CGPoint(x: self.containerFrame.maxX, y: self.containerFrame.minY), end: CGPoint(x: self.calculateTopRightToBottomLeftX(containerFrame: self.containerFrame, zanPoint: self.zanPoint), y: self.containerFrame.maxY), width: self.lineWidth, color: self.lineColor) 21 | return [lineLayer] 22 | }() 23 | 24 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 25 | let maskLayers = self.zanMaskLayers() 26 | let oneSideConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame.offsetBy(dx: self.containerFrame.width, dy: self.containerFrame.height), mask: maskLayers.oneSide) 27 | let otherSideConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame.offsetBy(dx: -self.containerFrame.width, dy: -self.containerFrame.height), mask: maskLayers.otherSide) 28 | return [oneSideConfig, otherSideConfig] 29 | }() 30 | 31 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor) { 32 | self.containerFrame = containerFrame 33 | self.zanPoint = zanPoint 34 | self.lineWidth = lineWidth 35 | self.lineColor = lineColor 36 | } 37 | 38 | } 39 | 40 | extension DiagonallyZanConfig { 41 | 42 | fileprivate func zanMaskLayers() -> (oneSide: CAShapeLayer, otherSide: CAShapeLayer) { 43 | 44 | let bottomX = calculateTopRightToBottomLeftX(containerFrame: containerFrame, zanPoint: zanPoint) 45 | let oneSidePath = rightAreaBezierPath(bottomX: bottomX) 46 | let oneSideLayer = CAShapeLayer() 47 | oneSideLayer.path = oneSidePath.cgPath 48 | 49 | let otherSidePath = leftAreaBezierPath(bottomX: bottomX) 50 | let otherSideLayer = CAShapeLayer() 51 | otherSideLayer.path = otherSidePath.cgPath 52 | 53 | return (oneSideLayer, otherSideLayer) 54 | } 55 | 56 | fileprivate func rightAreaBezierPath(bottomX: CGFloat) -> UIBezierPath { 57 | 58 | let oneSidePath = UIBezierPath() 59 | oneSidePath.move(to: CGPoint(x: containerFrame.maxX, y: containerFrame.minY)) 60 | oneSidePath.addLine(to: zanPoint) 61 | oneSidePath.addLine(to: CGPoint(x: bottomX, y: containerFrame.maxY)) 62 | oneSidePath.addLine(to: CGPoint(x: containerFrame.maxX, y: containerFrame.maxY)) 63 | oneSidePath.addLine(to: CGPoint(x: containerFrame.maxX, y: containerFrame.minY)) 64 | oneSidePath.close() 65 | 66 | return oneSidePath 67 | } 68 | 69 | fileprivate func leftAreaBezierPath(bottomX: CGFloat) -> UIBezierPath { 70 | 71 | let otherSidePath = UIBezierPath() 72 | otherSidePath.move(to: CGPoint(x: containerFrame.minX, y: containerFrame.minY)) 73 | otherSidePath.addLine(to: CGPoint(x: containerFrame.maxX, y: containerFrame.minY)) 74 | otherSidePath.addLine(to: CGPoint(x: bottomX, y: containerFrame.maxY)) 75 | otherSidePath.addLine(to: CGPoint(x: containerFrame.minX, y: containerFrame.maxY)) 76 | otherSidePath.addLine(to: CGPoint(x: containerFrame.minX, y: containerFrame.minY)) 77 | otherSidePath.close() 78 | 79 | return otherSidePath 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/HorizontalZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HorizontalZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/07. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class HorizontalZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | 18 | //conform SamuraiConfigProtocol 19 | lazy var lineLayers: [CAShapeLayer] = { 20 | let lineLayer = self.zanLineLayer(from: CGPoint(x: self.containerFrame.minX, y: self.zanPoint.y), end: CGPoint(x: self.containerFrame.maxX, y: self.zanPoint.y), width: self.lineWidth, color: self.lineColor) 21 | return [lineLayer] 22 | }() 23 | 24 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 25 | let divided = self.containerFrame.divided(atDistance: self.zanPoint.y, from: .minYEdge) 26 | let slice = divided.slice 27 | let remainder = divided.remainder 28 | 29 | let oneSideConfig = ZanViewConfig(inSideFrame: slice, outSideFrame: slice.offsetBy(dx: 0.0, dy: -slice.height)) 30 | let otherSideConfig = ZanViewConfig(inSideFrame: remainder, outSideFrame: remainder.offsetBy(dx: 0.0, dy: remainder.height)) 31 | 32 | return [oneSideConfig, otherSideConfig] 33 | }() 34 | 35 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor) { 36 | self.containerFrame = containerFrame 37 | self.zanPoint = zanPoint 38 | self.lineWidth = lineWidth 39 | self.lineColor = lineColor 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/JaggedZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JaggedZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/16. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class JaggedZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | let jaggedWidth: CGFloat 18 | 19 | fileprivate lazy var jaggedRatio: CGFloat = { 20 | let zanWidth = self.containerFrame.maxX - self.zanPoint.x 21 | let ratio = self.zanPoint.y / zanWidth 22 | if ratio.isInfinite { 23 | fatalError("It will be infinite.") 24 | } 25 | return ratio 26 | }() 27 | 28 | fileprivate lazy var jaggedHeight: CGFloat = { 29 | return self.jaggedWidth * self.jaggedRatio 30 | }() 31 | 32 | fileprivate lazy var jaggedStartPoint: CGPoint = { 33 | return CGPoint(x: self.containerFrame.maxX - self.lineWidth, y: self.containerFrame.minY) 34 | }() 35 | 36 | fileprivate var leftAreaOffsetSize: CGSize 37 | fileprivate var rightAreaOffsetSize: CGSize 38 | 39 | //conform SamuraiConfigProtocol 40 | lazy var lineLayers: [CAShapeLayer] = { 41 | let path = self.jaggedPath() 42 | let lineLayer = self.zanLineLayer(from: path, width: self.lineWidth, color: self.lineColor) 43 | 44 | return [lineLayer] 45 | }() 46 | 47 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 48 | 49 | let left = self.containerFrame 50 | let right = self.containerFrame 51 | let maskLayer = self.zanMaskLayers() 52 | 53 | let oneSideConfig = ZanViewConfig(inSideFrame: left, outSideFrame: left.offsetBy(dx: -self.leftAreaOffsetSize.width, dy: -self.leftAreaOffsetSize.height), mask: maskLayer.leftAreaMask) 54 | let otherSideConfig = ZanViewConfig(inSideFrame: right, outSideFrame: right.offsetBy(dx: self.rightAreaOffsetSize.width, dy: self.rightAreaOffsetSize.height), mask: maskLayer.rightAreaMask) 55 | 56 | return [oneSideConfig, otherSideConfig] 57 | }() 58 | 59 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor, jaggedWidth: CGFloat) { 60 | self.containerFrame = containerFrame 61 | self.zanPoint = zanPoint 62 | self.lineWidth = lineWidth 63 | self.lineColor = lineColor 64 | self.jaggedWidth = jaggedWidth > 0.0 ? jaggedWidth : 4.0 65 | self.leftAreaOffsetSize = self.containerFrame.size 66 | self.rightAreaOffsetSize = self.containerFrame.size 67 | } 68 | 69 | } 70 | 71 | extension JaggedZanConfig { 72 | 73 | fileprivate func zanMaskLayers() -> (leftAreaMask: CAShapeLayer, rightAreaMask: CAShapeLayer) { 74 | 75 | let leftAreaMaskLayer = CAShapeLayer() 76 | let leftAreaPath = serratedLeftAreaPath() 77 | leftAreaMaskLayer.path = leftAreaPath.cgPath 78 | 79 | let rightAreaMaskLayer = CAShapeLayer() 80 | let rightAreaPath = serratedRightAreaPath() 81 | rightAreaMaskLayer.path = rightAreaPath.cgPath 82 | 83 | return (leftAreaMaskLayer, rightAreaMaskLayer) 84 | 85 | } 86 | 87 | fileprivate func jaggedPath() -> UIBezierPath { 88 | 89 | let stepWidth = jaggedWidth * 2 90 | let path = UIBezierPath() 91 | path.move(to: jaggedStartPoint) 92 | while true { 93 | path.addLine(to: CGPoint(x: path.currentPoint.x + jaggedWidth, y: path.currentPoint.y + jaggedHeight)) 94 | path.addLine(to: CGPoint(x: path.currentPoint.x - stepWidth, y: path.currentPoint.y)) 95 | if path.currentPoint.y > containerFrame.maxY || path.currentPoint.x < 0.0 { 96 | break 97 | } 98 | } 99 | 100 | return path 101 | 102 | } 103 | 104 | private func serratedLeftAreaPath() -> UIBezierPath { 105 | 106 | let path = jaggedPath() 107 | leftAreaOffsetSize = CGSize(width: jaggedStartPoint.x, height: path.currentPoint.y) 108 | path.addLine(to: CGPoint(x: containerFrame.minX, y: containerFrame.maxY)) 109 | path.addLine(to: CGPoint(x: containerFrame.minX, y: containerFrame.minY)) 110 | path.addLine(to: jaggedStartPoint) 111 | 112 | return path 113 | 114 | } 115 | 116 | private func serratedRightAreaPath() -> UIBezierPath { 117 | 118 | let path = jaggedPath() 119 | let rightAreaWidth = path.currentPoint.x <= 0.0 ? containerFrame.maxX : containerFrame.maxX - path.currentPoint.x 120 | rightAreaOffsetSize = CGSize(width: rightAreaWidth, height: containerFrame.maxY) 121 | path.addLine(to: CGPoint(x: path.currentPoint.x, y: containerFrame.maxY)) 122 | path.addLine(to: CGPoint(x: containerFrame.maxX, y: containerFrame.maxY)) 123 | path.addLine(to: CGPoint(x: containerFrame.maxX, y: containerFrame.minY)) 124 | path.addLine(to: jaggedStartPoint) 125 | 126 | return path 127 | 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/RectangleZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RectangleZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Takahiro Nishinobu on 2016/12/18. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class RectangleZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | let rectangleWidth: CGFloat 18 | let rectangleHeight: CGFloat 19 | let cornerRadius: CGFloat 20 | 21 | //conform SamuraiConfigProtocol 22 | lazy var lineLayers: [CAShapeLayer] = { 23 | let path = self.rectangleAreaPath() 24 | let lineLayer = self.zanLineLayer(from: path, width: self.lineWidth, color: self.lineColor) 25 | return [lineLayer] 26 | }() 27 | 28 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 29 | let maskLayers = self.zanMaskLayers() 30 | let oneSideConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame.offsetBy(dx: 0.0, dy: self.containerFrame.maxY), isAlphaAnimation: true, mask: maskLayers.oneSide) 31 | let otherSideConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame, mask: maskLayers.otherSide) 32 | return [oneSideConfig, otherSideConfig] 33 | }() 34 | 35 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor, rectangleWidth: CGFloat, rectangleHeight: CGFloat, cornerRadius: CGFloat) { 36 | self.containerFrame = containerFrame 37 | self.zanPoint = zanPoint 38 | self.lineWidth = lineWidth 39 | self.lineColor = lineColor 40 | self.rectangleWidth = rectangleWidth 41 | self.rectangleHeight = rectangleHeight 42 | self.cornerRadius = cornerRadius 43 | } 44 | 45 | } 46 | 47 | extension RectangleZanConfig { 48 | 49 | fileprivate func rectangleAreaPath() -> UIBezierPath { 50 | let x: CGFloat = zanPoint.x - rectangleWidth / 2.0 51 | let y: CGFloat = zanPoint.y - rectangleHeight / 2.0 52 | let path = UIBezierPath(roundedRect: CGRect(x: x, y: y, width: rectangleWidth, height: rectangleHeight), cornerRadius: cornerRadius) 53 | return path 54 | } 55 | 56 | fileprivate func zanMaskLayers() -> (oneSide: CAShapeLayer, otherSide: CAShapeLayer) { 57 | 58 | let oneSide = CAShapeLayer() 59 | let outerRectanglePath = rectangleAreaPath() 60 | outerRectanglePath.addLine(to: CGPoint(x: outerRectanglePath.currentPoint.x, y: containerFrame.minY)) 61 | outerRectanglePath.addLine(to: CGPoint(x: containerFrame.minX, y: outerRectanglePath.currentPoint.y)) 62 | outerRectanglePath.addLine(to: CGPoint(x: outerRectanglePath.currentPoint.x, y: containerFrame.maxY)) 63 | outerRectanglePath.addLine(to: CGPoint(x: containerFrame.maxX, y: outerRectanglePath.currentPoint.y)) 64 | outerRectanglePath.addLine(to: CGPoint(x: outerRectanglePath.currentPoint.x, y: containerFrame.minY)) 65 | outerRectanglePath.addLine(to: CGPoint(x: containerFrame.minX, y: outerRectanglePath.currentPoint.y)) 66 | oneSide.path = outerRectanglePath.cgPath 67 | 68 | let otherSide = CAShapeLayer() 69 | let innerRectanglePath = rectangleAreaPath() 70 | otherSide.path = innerRectanglePath.cgPath 71 | 72 | return (oneSide, otherSide) 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/SamuraiConfigProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZanConfigProtocol.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/07. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol SamuraiConfigProtocol { 12 | 13 | var lineLayers: [CAShapeLayer] { get } 14 | var zanViewConfigList: [ZanViewConfigProtocol] { get } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/ShreddedZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShreddedZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/26. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class ShreddedZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | let isHorizontal: Bool 18 | let shreddedCount: Int 19 | 20 | private let limitCount: Int = 50 21 | 22 | lazy var oneSide: CGFloat = { 23 | if self.isHorizontal { 24 | return self.containerFrame.maxY / CGFloat(self.shreddedCount) 25 | } 26 | return self.containerFrame.maxX / CGFloat(self.shreddedCount) 27 | }() 28 | 29 | //conform SamuraiConfigProtocol 30 | lazy var lineLayers: [CAShapeLayer] = { 31 | return self.shreddedLineLayers() 32 | }() 33 | 34 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 35 | return self.zanViewConfigs() 36 | }() 37 | 38 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor, isHorizontal: Bool, shreddedCount: Int) { 39 | self.containerFrame = containerFrame 40 | self.zanPoint = zanPoint 41 | self.lineWidth = lineWidth 42 | self.lineColor = lineColor 43 | self.isHorizontal = isHorizontal 44 | self.shreddedCount = shreddedCount > limitCount ? limitCount : shreddedCount 45 | } 46 | 47 | } 48 | 49 | extension ShreddedZanConfig { 50 | 51 | fileprivate func shreddedLineLayers() -> [CAShapeLayer] { 52 | 53 | return (1...shreddedCount).map { count -> CAShapeLayer in 54 | 55 | let position = oneSide * CGFloat(count) 56 | let path = UIBezierPath() 57 | let isEven: Bool = count % 2 == 0 58 | 59 | if isHorizontal { 60 | 61 | if isEven { 62 | path.move(to: CGPoint(x: containerFrame.minX, y: position)) 63 | path.addLine(to: CGPoint(x: containerFrame.maxX, y: position)) 64 | } else { 65 | path.move(to: CGPoint(x: containerFrame.maxX, y: position)) 66 | path.addLine(to: CGPoint(x: containerFrame.minX, y: position)) 67 | } 68 | 69 | } else { 70 | 71 | if isEven { 72 | path.move(to: CGPoint(x: position, y: containerFrame.minY)) 73 | path.addLine(to: CGPoint(x: position, y: containerFrame.maxY)) 74 | } else { 75 | path.move(to: CGPoint(x: position, y: containerFrame.maxY)) 76 | path.addLine(to: CGPoint(x: position, y: containerFrame.minY)) 77 | } 78 | 79 | } 80 | 81 | let shreddedLayer = zanLineLayer(from: path, width: lineWidth, color: lineColor) 82 | 83 | return shreddedLayer 84 | } 85 | 86 | } 87 | 88 | fileprivate func zanViewConfigs() -> [ZanViewConfigProtocol] { 89 | 90 | return (0.. ZanViewConfigProtocol in 91 | 92 | let point = oneSide * CGFloat(count) 93 | let inSideFrame: CGRect 94 | let outSideFrame: CGRect 95 | let isEven: Bool = count % 2 == 0 96 | 97 | if isHorizontal { 98 | inSideFrame = CGRect(x: containerFrame.minX, y: point, width: containerFrame.maxX, height: oneSide) 99 | let outDistance = isEven ? -(point + oneSide) : (containerFrame.maxY - point) 100 | outSideFrame = inSideFrame.offsetBy(dx: 0.0, dy: outDistance) 101 | } else { 102 | inSideFrame = CGRect(x: point, y: containerFrame.minY, width: oneSide, height: containerFrame.maxY) 103 | let outDistance = isEven ? -(point + oneSide) : (containerFrame.maxX - point) 104 | outSideFrame = inSideFrame.offsetBy(dx: outDistance, dy: 0.0) 105 | } 106 | 107 | return ZanViewConfig(inSideFrame: inSideFrame, outSideFrame: outSideFrame) 108 | } 109 | 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/TriangleZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TriangleZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/19. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class TriangleZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | let oneSide: CGFloat 18 | 19 | //conform SamuraiConfigProtocol 20 | lazy var lineLayers: [CAShapeLayer] = { 21 | 22 | let path = self.trianglePath() 23 | let triangleLineLayer = self.zanLineLayer(from: path, width: self.lineWidth, color: self.lineColor) 24 | 25 | return [triangleLineLayer] 26 | }() 27 | 28 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 29 | 30 | let maskLayers = self.zanMaskLayers() 31 | let oneSideConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame.offsetBy(dx: 0.0, dy: self.containerFrame.maxY), isAlphaAnimation: true, mask: maskLayers.oneSide) 32 | let otherSideConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame, mask: maskLayers.otherSide) 33 | return [oneSideConfig, otherSideConfig] 34 | 35 | }() 36 | 37 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor, oneSide: CGFloat) { 38 | self.containerFrame = containerFrame 39 | self.zanPoint = zanPoint 40 | self.lineWidth = lineWidth 41 | self.lineColor = lineColor 42 | self.oneSide = oneSide 43 | } 44 | 45 | } 46 | 47 | extension TriangleZanConfig { 48 | 49 | fileprivate func zanMaskLayers() -> (oneSide: CAShapeLayer, otherSide: CAShapeLayer) { 50 | 51 | let oneSide = CAShapeLayer() 52 | let outerTrianglePath = trianglePath() 53 | outerTrianglePath.addLine(to: CGPoint(x: outerTrianglePath.currentPoint.x, y: containerFrame.minY)) 54 | outerTrianglePath.addLine(to: CGPoint(x: containerFrame.maxX, y: outerTrianglePath.currentPoint.y)) 55 | outerTrianglePath.addLine(to: CGPoint(x: outerTrianglePath.currentPoint.x, y: containerFrame.maxY)) 56 | outerTrianglePath.addLine(to: CGPoint(x: containerFrame.minX, y: outerTrianglePath.currentPoint.y)) 57 | outerTrianglePath.addLine(to: CGPoint(x: outerTrianglePath.currentPoint.x, y: containerFrame.minY)) 58 | outerTrianglePath.addLine(to: CGPoint(x: containerFrame.maxX, y: outerTrianglePath.currentPoint.y)) 59 | oneSide.path = outerTrianglePath.cgPath 60 | 61 | let otherSide = CAShapeLayer() 62 | let innerTrianglePath = trianglePath() 63 | otherSide.path = innerTrianglePath.cgPath 64 | 65 | return (oneSide, otherSide) 66 | 67 | } 68 | 69 | fileprivate func trianglePath() -> UIBezierPath { 70 | let path = UIBezierPath() 71 | path.move(to: CGPoint(x: zanPoint.x, y: zanPoint.y - oneSide / 2.0)) 72 | path.addLine(to: CGPoint(x: path.currentPoint.x - oneSide / 2.0, y: path.currentPoint.y + oneSide)) 73 | path.addLine(to: CGPoint(x: path.currentPoint.x + oneSide, y: path.currentPoint.y)) 74 | path.addLine(to: CGPoint(x: zanPoint.x, y: zanPoint.y - oneSide / 2.0)) 75 | return path 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/VerticalZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VerticalZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/07. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class VerticalZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | 18 | //conform SamuraiConfigProtocol 19 | lazy var lineLayers: [CAShapeLayer] = { 20 | let lineLayer = self.zanLineLayer(from: CGPoint(x: self.zanPoint.x, y: self.containerFrame.minY), end: CGPoint(x: self.zanPoint.x, y: self.containerFrame.maxY), width: self.lineWidth, color: self.lineColor) 21 | return [lineLayer] 22 | }() 23 | 24 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 25 | let divided = self.containerFrame.divided(atDistance: self.zanPoint.x, from: .minXEdge) 26 | let slice = divided.slice 27 | let remainder = divided.remainder 28 | 29 | let oneSideConfig = ZanViewConfig(inSideFrame: slice, outSideFrame: slice.offsetBy(dx: -slice.width, dy: 0.0)) 30 | let otherSideConfig = ZanViewConfig(inSideFrame: remainder, outSideFrame: remainder.offsetBy(dx: remainder.width, dy: 0.0)) 31 | 32 | return [oneSideConfig, otherSideConfig] 33 | }() 34 | 35 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor) { 36 | self.containerFrame = containerFrame 37 | self.zanPoint = zanPoint 38 | self.lineWidth = lineWidth 39 | self.lineColor = lineColor 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/XZanConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XZanConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/12. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class XZanConfig: ZanLineProtocol, SamuraiConfigProtocol { 12 | 13 | let containerFrame: CGRect 14 | let zanPoint: CGPoint 15 | let lineWidth: CGFloat 16 | let lineColor: UIColor 17 | 18 | //conform SamuraiConfigProtocol 19 | lazy var lineLayers: [CAShapeLayer] = { 20 | 21 | let oneCrossLineLayer = self.zanLineLayer(from: CGPoint(x: self.containerFrame.maxX, y: 0.0), end: CGPoint(x: self.calculateTopRightToBottomLeftX(containerFrame: self.containerFrame, zanPoint: self.zanPoint), y: self.containerFrame.maxY), width: self.lineWidth, color: self.lineColor) 22 | let otherCrossLineLayer = self.zanLineLayer(from: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: self.calculateTopLeftToBottomRightX(containerFrame: self.containerFrame, zanPoint: self.zanPoint), y: self.containerFrame.maxY), width: self.lineWidth, color: self.lineColor) 23 | 24 | return [oneCrossLineLayer, otherCrossLineLayer] 25 | }() 26 | 27 | lazy var zanViewConfigList: [ZanViewConfigProtocol] = { 28 | 29 | let xLayers = self.zanXMaskLayers() 30 | let topViewConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame.offsetBy(dx: 0.0, dy: -self.zanPoint.y), mask: xLayers.top) 31 | let leftViewConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame.offsetBy(dx: -self.zanPoint.x, dy: 0.0), mask: xLayers.left) 32 | let bottomViewConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame.offsetBy(dx: 0.0, dy: (self.containerFrame.height - self.zanPoint.y)), mask: xLayers.bottom) 33 | let rightViewConfig = ZanViewConfig(inSideFrame: self.containerFrame, outSideFrame: self.containerFrame.offsetBy(dx: self.containerFrame.width - self.zanPoint.x, dy: 0.0), mask: xLayers.right) 34 | 35 | return [topViewConfig, leftViewConfig, bottomViewConfig, rightViewConfig] 36 | 37 | }() 38 | 39 | init(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, color: UIColor) { 40 | self.containerFrame = containerFrame 41 | self.zanPoint = zanPoint 42 | self.lineWidth = lineWidth 43 | self.lineColor = color 44 | } 45 | 46 | } 47 | 48 | extension XZanConfig { 49 | 50 | fileprivate func zanXMaskLayers() -> (top: CAShapeLayer, left: CAShapeLayer, bottom: CAShapeLayer, right: CAShapeLayer) { 51 | 52 | let topLeftSideRightAnglePoint = CGPoint(x: containerFrame.minX, y: containerFrame.minY) 53 | let topRightSideRightAnglePoint = CGPoint(x: containerFrame.maxX, y: containerFrame.minY) 54 | let bottomLeftSideRightAnglePoint = CGPoint(x: containerFrame.minX, y: containerFrame.maxY) 55 | let bottomRightSideRightAnglePoint = CGPoint(x: containerFrame.maxX, y: containerFrame.maxY) 56 | let bottomLeftPoint = CGPoint(x: calculateTopRightToBottomLeftX(containerFrame: containerFrame, zanPoint: zanPoint), y: containerFrame.maxY) 57 | let bottomRightPoint = CGPoint(x: calculateTopLeftToBottomRightX(containerFrame: containerFrame, zanPoint: zanPoint), y: containerFrame.maxY) 58 | 59 | let topAreaPath = triangleAreaPath(point1: topLeftSideRightAnglePoint, point2: zanPoint, point3: topRightSideRightAnglePoint) 60 | let leftAreaPath = rectangleAreaPath(point1: topLeftSideRightAnglePoint, point2: zanPoint, point3: bottomLeftPoint, point4: bottomLeftSideRightAnglePoint) 61 | let bottomAreaPath = triangleAreaPath(point1: bottomLeftPoint, point2: zanPoint, point3: bottomRightPoint) 62 | let rightAreaPath = rectangleAreaPath(point1: topRightSideRightAnglePoint, point2: zanPoint, point3: bottomRightPoint, point4: bottomRightSideRightAnglePoint) 63 | 64 | let topAreaLayer = CAShapeLayer() 65 | topAreaLayer.path = topAreaPath.cgPath 66 | 67 | let leftAreaLayer = CAShapeLayer() 68 | leftAreaLayer.path = leftAreaPath.cgPath 69 | 70 | let bottomAreaLayer = CAShapeLayer() 71 | bottomAreaLayer.path = bottomAreaPath.cgPath 72 | 73 | let rightAreaLayer = CAShapeLayer() 74 | rightAreaLayer.path = rightAreaPath.cgPath 75 | 76 | return (topAreaLayer, leftAreaLayer, bottomAreaLayer, rightAreaLayer) 77 | 78 | } 79 | 80 | private func triangleAreaPath(point1: CGPoint, point2: CGPoint, point3: CGPoint) -> UIBezierPath { 81 | let path = UIBezierPath() 82 | path.move(to: point1) 83 | path.addLine(to: point2) 84 | path.addLine(to: point3) 85 | path.addLine(to: point1) 86 | path.close() 87 | 88 | return path 89 | } 90 | 91 | private func rectangleAreaPath(point1: CGPoint, point2: CGPoint, point3: CGPoint, point4: CGPoint) -> UIBezierPath { 92 | let path = UIBezierPath() 93 | path.move(to: point1) 94 | path.addLine(to: point2) 95 | path.addLine(to: point3) 96 | path.addLine(to: point4) 97 | path.addLine(to: point1) 98 | path.close() 99 | 100 | return path 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/ZanLineProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZanLineProtocol.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/07. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol ZanLineProtocol { 12 | 13 | func zanLineLayer(from start: CGPoint, end: CGPoint, width: CGFloat, color: UIColor) -> CAShapeLayer 14 | func calculateTopRightToBottomLeftX(containerFrame: CGRect, zanPoint: CGPoint) -> CGFloat 15 | func calculateTopLeftToBottomRightX(containerFrame: CGRect, zanPoint: CGPoint) -> CGFloat 16 | 17 | } 18 | 19 | public extension ZanLineProtocol { 20 | 21 | func zanLineLayer(from start: CGPoint, end: CGPoint, width: CGFloat, color: UIColor) -> CAShapeLayer { 22 | 23 | let path = UIBezierPath() 24 | path.move(to: start) 25 | path.addLine(to: end) 26 | let lineLayer = zanLineLayer(from: path, width: width, color: color) 27 | return lineLayer 28 | 29 | } 30 | 31 | func zanLineLayer(from path: UIBezierPath, width: CGFloat, color: UIColor) -> CAShapeLayer { 32 | 33 | let zanLineLayer = CAShapeLayer() 34 | zanLineLayer.path = path.cgPath 35 | zanLineLayer.fillColor = nil 36 | zanLineLayer.strokeColor = color.cgColor 37 | zanLineLayer.lineWidth = width 38 | return zanLineLayer 39 | 40 | } 41 | 42 | func calculateTopRightToBottomLeftX(containerFrame: CGRect, zanPoint: CGPoint) -> CGFloat { 43 | 44 | let ratio = calculateRatioY(containerFrame: containerFrame, zanPoint: zanPoint) 45 | let width = (containerFrame.maxX - zanPoint.x) * ratio 46 | let bottomX = containerFrame.maxX - width 47 | 48 | return bottomX 49 | } 50 | 51 | func calculateTopLeftToBottomRightX(containerFrame: CGRect, zanPoint: CGPoint) -> CGFloat { 52 | 53 | let ratio = calculateRatioY(containerFrame: containerFrame, zanPoint: zanPoint) 54 | let bottomX = zanPoint.x * ratio 55 | 56 | return bottomX 57 | } 58 | 59 | private func calculateRatioY(containerFrame: CGRect, zanPoint: CGPoint) -> CGFloat { 60 | let ratio = containerFrame.maxY / zanPoint.y 61 | if ratio.isInfinite { 62 | fatalError("zanPosition.y is not 0. It will be infinite.") 63 | } 64 | return ratio 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/ZanViewConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZanViewConfig.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/05. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct ZanViewConfig: ZanViewConfigProtocol { 12 | 13 | let inSideFrame: CGRect 14 | let outSideFrame: CGRect 15 | let mask: CAShapeLayer? 16 | let isAlphaAnimation: Bool 17 | let isScaleAnimation: Bool 18 | 19 | init(inSideFrame: CGRect, outSideFrame: CGRect, isAlphaAnimation: Bool = false, mask: CAShapeLayer? = nil, isScaleAnimation: Bool = false) { 20 | self.inSideFrame = inSideFrame 21 | self.outSideFrame = outSideFrame 22 | self.isAlphaAnimation = isAlphaAnimation 23 | self.mask = mask 24 | self.isScaleAnimation = isScaleAnimation 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Config/ZanViewConfigProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZanViewConfigProtocol.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Nishinobu.Takahiro on 2016/12/07. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol ZanViewConfigProtocol { 12 | 13 | var inSideFrame: CGRect { get } 14 | var outSideFrame: CGRect { get } 15 | var isAlphaAnimation: Bool { get } 16 | var mask: CAShapeLayer? { get } 17 | var isScaleAnimation: Bool { get } 18 | 19 | } 20 | 21 | extension ZanViewConfigProtocol { 22 | 23 | func viewFrame(isPresenting: Bool) -> CGRect { 24 | return isPresenting ? inSideFrame : outSideFrame 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /SamuraiTransition/Zan/Zan.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Zan.swift 3 | // SamuraiTransition 4 | // 5 | // Created by Takahiro Nishinobu on 2016/11/26. 6 | // Copyright © 2016年 hachinobu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum Zan { 12 | 13 | case horizontal 14 | case vertical 15 | case diagonally 16 | case cross 17 | case x 18 | case jagged(width: CGFloat) 19 | case circle(radius: CGFloat) 20 | case rectangle(width: CGFloat, height: CGFloat, cornerRadius: CGFloat) 21 | case triangle(oneSide: CGFloat) 22 | case shredded(isHorizontal: Bool, shreddedCount: Int) 23 | case chopped(oneSide: CGFloat) 24 | 25 | func samuraiConfig(containerFrame: CGRect, zanPoint: CGPoint, lineWidth: CGFloat, lineColor: UIColor) -> SamuraiConfigProtocol { 26 | 27 | switch self { 28 | case .horizontal: 29 | return HorizontalZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, lineColor: lineColor) 30 | 31 | case .vertical: 32 | return VerticalZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, lineColor: lineColor) 33 | 34 | case .diagonally: 35 | return DiagonallyZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, lineColor: lineColor) 36 | 37 | case .cross: 38 | return CrossZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, lineColor: lineColor) 39 | 40 | case .x: 41 | return XZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, color: lineColor) 42 | 43 | case let .jagged(jaggedWidth): 44 | return JaggedZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, lineColor: lineColor, jaggedWidth: jaggedWidth) 45 | 46 | case let .circle(radius): 47 | return CircleZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, lineColor: lineColor, radius: radius) 48 | 49 | case let .rectangle(width, height, cornerRadius): 50 | return RectangleZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, lineColor: lineColor, rectangleWidth: width, rectangleHeight: height, cornerRadius: cornerRadius) 51 | 52 | case let .triangle(oneSide): 53 | return TriangleZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, lineColor: lineColor, oneSide: oneSide) 54 | 55 | case let .shredded(isHorizontal, shreddedCount): 56 | return ShreddedZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, lineColor: lineColor, isHorizontal: isHorizontal, shreddedCount: shreddedCount) 57 | 58 | case let .chopped(oneSide): 59 | return ChoppedZanConfig(containerFrame: containerFrame, zanPoint: zanPoint, lineWidth: lineWidth, lineColor: lineColor, oneSide: oneSide) 60 | 61 | } 62 | 63 | } 64 | 65 | } 66 | --------------------------------------------------------------------------------