├── Example
├── Example
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── Icon.png
│ │ │ ├── Icon-60.png
│ │ │ ├── Icon-72.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon@2x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-72@2x.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-60@2x-1.png
│ │ │ ├── Icon-60@3x-1.png
│ │ │ ├── Icon-Small-40.png
│ │ │ ├── Icon-Small-50.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ ├── Icon-Small@3x.png
│ │ │ ├── Icon-Small-40@2x.png
│ │ │ ├── Icon-Small-40@3x.png
│ │ │ ├── Icon-Small-50@2x.png
│ │ │ ├── iTunesArtwork@2x.png
│ │ │ └── Contents.json
│ │ ├── samurai.imageset
│ │ │ ├── samurai@2x.png
│ │ │ └── Contents.json
│ │ ├── samurai2.imageset
│ │ │ ├── samurai2@2x.png
│ │ │ └── Contents.json
│ │ └── splash_samurai.imageset
│ │ │ ├── splash_samurai.png
│ │ │ ├── splash_samurai@2x.png
│ │ │ ├── splash_samurai@3x.png
│ │ │ └── Contents.json
│ ├── ModalViewController.swift
│ ├── Info.plist
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ └── ViewController.swift
└── Example.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── project.pbxproj
├── SamuraiTransition.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcshareddata
│ └── xcschemes
│ │ └── SamuraiTransition.xcscheme
└── project.pbxproj
├── SamuraiTransition
├── Zan
│ ├── Config
│ │ ├── SamuraiConfigProtocol.swift
│ │ ├── ZanViewConfigProtocol.swift
│ │ ├── ZanViewConfig.swift
│ │ ├── VerticalZanConfig.swift
│ │ ├── HorizontalZanConfig.swift
│ │ ├── ZanLineProtocol.swift
│ │ ├── CrossZanConfig.swift
│ │ ├── CircleZanConfig.swift
│ │ ├── TriangleZanConfig.swift
│ │ ├── RectangleZanConfig.swift
│ │ ├── DiagonallyZanConfig.swift
│ │ ├── ChoppedZanConfig.swift
│ │ ├── ShreddedZanConfig.swift
│ │ ├── JaggedZanConfig.swift
│ │ └── XZanConfig.swift
│ └── Zan.swift
├── SamuraiTransition.h
├── Info.plist
├── ViewController
│ └── SamuraiViewController.swift
└── SamuraiTransition.swift
├── SamuraiTransition.podspec
├── LICENSE
├── .gitignore
└── README.md
/Example/Example/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-72.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon@2x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/samurai.imageset/samurai@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/samurai.imageset/samurai@2x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/samurai2.imageset/samurai2@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/samurai2.imageset/samurai2@2x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@2x-1.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@3x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-60@3x-1.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-40.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/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/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/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/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/Example/Example/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/splash_samurai.imageset/splash_samurai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hachinobu/SamuraiTransition/HEAD/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/HEAD/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/HEAD/Example/Example/Assets.xcassets/splash_samurai.imageset/splash_samurai@3x.png
--------------------------------------------------------------------------------
/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SamuraiTransition.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 |
--------------------------------------------------------------------------------
/SamuraiTransition.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/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/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 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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 | }
--------------------------------------------------------------------------------
/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/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/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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.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/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/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/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/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/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/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/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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
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 | |||||
13 |
14 | |x|jagged|circle|rectangle|
15 | |:--:|:--:|:--:|:--:|
16 | |||||
17 |
18 | |triangle|shredded|chopped|
19 | |:--:|:--:|:--:|
20 | ||||
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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------