├── .gitignore ├── LICENSE ├── README.md ├── TransitionManager.podspec ├── TransitionManager.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── TransitionManager.xccheckout │ └── xcuserdata │ │ └── Cem.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── cem.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── TransitionManager.xcscheme │ └── xcschememanagement.plist ├── TransitionManager ├── Demo │ ├── AnimationHelper.swift │ ├── TransitionAnimations.swift │ └── ViewController.swift ├── Source │ └── TransitionManager.swift └── SupportingFiles │ ├── AppDelegate.swift │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ └── Info.plist └── TransitionManagerTests ├── Info.plist └── TransitionManagerTests.swift /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/swift,xcode 3 | 4 | ### Swift ### 5 | # Xcode 6 | # 7 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 8 | 9 | ## Build generated 10 | build/ 11 | DerivedData/ 12 | 13 | ## Various settings 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata/ 23 | 24 | ## Other 25 | *.moved-aside 26 | *.xcuserstate 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | *.dSYM.zip 32 | *.dSYM 33 | 34 | ## Playgrounds 35 | timeline.xctimeline 36 | playground.xcworkspace 37 | 38 | # Swift Package Manager 39 | # 40 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 41 | # Packages/ 42 | .build/ 43 | 44 | # CocoaPods 45 | # 46 | # We recommend against adding the Pods directory to your .gitignore. However 47 | # you should judge for yourself, the pros and cons are mentioned at: 48 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 49 | # 50 | Pods/ 51 | 52 | # Carthage 53 | # 54 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 55 | Carthage/Checkouts 56 | 57 | Carthage/Build 58 | 59 | # fastlane 60 | # 61 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 62 | # screenshots whenever they are needed. 63 | # For more information about the recommended setup visit: 64 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 65 | 66 | fastlane/report.xml 67 | fastlane/Preview.html 68 | fastlane/screenshots 69 | fastlane/test_output 70 | 71 | 72 | ### Xcode ### 73 | # Xcode 74 | # 75 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 76 | 77 | ## Build generated 78 | 79 | ## Various settings 80 | 81 | ## Other 82 | *.xccheckout 83 | *.xcscmblueprint 84 | 85 | # Docs 86 | docs/ 87 | 88 | # End of https://www.gitignore.io/api/swift,xcode 89 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2015, Cem Olcay 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TransitionManager 2 | ================= 3 | 4 | Painless custom transitioning. Easy extend, easy setup, just focus on animations. 5 | 6 | ## Installation 7 | 8 | #### CocoaPods 9 | You can use [CocoaPods](http://cocoapods.org/) to install `TransitionManager` by adding it to your `Podfile`: 10 | 11 | ```ruby 12 | platform :ios, '8.0' 13 | use_frameworks! 14 | pod 'TransitionManager' 15 | ``` 16 | 17 | To get the full benefits import `TransitionManager` wherever you import UIKit 18 | 19 | ``` swift 20 | import UIKit 21 | import TransitionManager 22 | ``` 23 | #### Manually 24 | 1. Download and drop ```/TransitionManager```folder in your project. 25 | 2. Congratulations! 26 | 27 | Usage 28 | ----- 29 | 30 | Copy & paste `TransitionManager.swift` into your project. 31 | 32 | - Declare a `TransitionManager` object. 33 | - Init it with a [`TransitionManagerAnimation`](#Create) 34 | - Assign it as your navigation controller's delegate if you use navigation controller. 35 | - Else assign it as your view controller's `transitioningDelegate`. 36 | 37 | ``` swift 38 | 39 | var transition: TransitionManager! 40 | 41 | override func viewDidLoad() { 42 | super.viewDidLoad() 43 | 44 | transition = TransitionManager (transitionAnimation: FadeTransitionAnimation()) 45 | navigationController?.delegate = transition 46 | } 47 | 48 | ``` 49 | 50 | 51 | Creating Transition Animations 52 | ----- 53 | 54 | 55 | Create a subclass of `TransitionManagerAnimation` 56 | 57 | ``` swift 58 | class FadeTransitionAnimation: TransitionManagerAnimation { 59 | 60 | } 61 | ``` 62 | 63 | `TransitionManagerAnimation` class implements `TransitionManagerDelegate` protocol. 64 | 65 | ##### TransitionManagerDelegate 66 | 67 | ``` swift 68 | protocol TransitionManagerDelegate { 69 | 70 | /// Transition nimation method implementation 71 | func transition( 72 | container: UIView, 73 | fromViewController: UIViewController, 74 | toViewController: UIViewController, 75 | isDismissing: Bool, 76 | duration: NSTimeInterval, 77 | completion: () -> Void) 78 | 79 | /// Interactive transitions, 80 | /// update percent in gesture handler 81 | var interactionTransitionController: UIPercentDrivenInteractiveTransition? { get set } 82 | } 83 | ``` 84 | 85 | For transition animation, we should override `transition` func and write our custom animation in it. 86 | 87 | ``` swift 88 | 89 | class FadeTransitionAnimation: TransitionManagerAnimation { 90 | override func transition( 91 | container: UIView, 92 | fromViewController: UIViewController, 93 | toViewController: UIViewController, 94 | isDismissing: Bool, 95 | duration: NSTimeInterval, 96 | completion: () -> Void) { 97 | if isDismissing { 98 | closeAnimation(container, 99 | fromViewController: fromViewController, 100 | toViewController: toViewController, 101 | duration: duration, 102 | completion: completion) 103 | } else { 104 | openAnimation(container, 105 | fromViewController: fromViewController, 106 | toViewController: toViewController, 107 | duration: duration, 108 | completion: completion) 109 | } 110 | } 111 | } 112 | 113 | ``` 114 | 115 | One important part is `completion()` must be called because the `TransitionManager` finishes transition after it gets called. 116 | 117 | 118 | ### Interaction Transition 119 | 120 | Interaction transition has 3 parts: 121 | * Init `interactionTransitionController` and either pop or push navigation controller when gesture (interaction) starts. 122 | * Calculate your `percent`s on gesture change and `updateInteractiveTransition:` with that percent 123 | * When gesture ended, decide if your transition complete or not and give information to your `interactionTransitionController` with `finishInteractiveTransition ()` and `cancelInteractiveTransition ()` 124 | 125 | 126 | ### Easier `TransitionManager` setup 127 | 128 | You can create a `TransitionManagerAnimation` container enum and give it all your animations 129 | 130 | ``` swift 131 | enum TransitionManagerAnimations { 132 | case Fade 133 | case Pull 134 | } 135 | ``` 136 | 137 | Write a func that returns correct transition animation in enum 138 | 139 | ``` swift 140 | enum TransitionManagerAnimations { 141 | case Fade 142 | case Pull 143 | 144 | func transitionAnimation () -> TransitionManagerAnimation { 145 | switch self { 146 | case .Fade: 147 | return FadeTransitionAnimation() 148 | case .Pull: 149 | return PullTransitionAnimation() 150 | } 151 | } 152 | } 153 | ``` 154 | 155 | Extend `TransitionManager` and write a new init method like 156 | 157 | ``` swift 158 | extension TransitionManager { 159 | convenience init(transition: TransitionManagerAnimations) { 160 | self.init(transitionAnimation: transition.transitionAnimation()) 161 | } 162 | } 163 | ``` 164 | 165 | Now you can create `TransitionManager` in your view controller like 166 | 167 | ``` swift 168 | transition = TransitionManager(transition: .Pull) 169 | navigationController?.delegate = transition 170 | ``` 171 | -------------------------------------------------------------------------------- /TransitionManager.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint TransitionManager.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "TransitionManager" 19 | s.version = "0.3" 20 | s.summary = "Painless custom transitioning. Easy extend, easy setup, just focus on animations." 21 | s.swift_version = "4.2" 22 | 23 | # This description is used to generate tags and improve search results. 24 | # * Think: What does it do? Why did you write it? What is the focus? 25 | # * Try to keep it short, snappy and to the point. 26 | # * Write the description between the DESC delimiters below. 27 | # * Finally, don't worry about the indent, CocoaPods strips it! 28 | s.description = <<-DESC 29 | TransitionManager 30 | ================= 31 | 32 | Painless custom transitioning. Easy extend, easy setup, just focus on animations. 33 | 34 | 35 | Usage 36 | ----- 37 | 38 | Copy & paste `TransitionManager.swift` into your project. 39 | 40 | - Declare a `TransitionManager` object. 41 | - Init it with a [`TransitionManagerAnimation`](#Create) 42 | - Assign it as your navigation controller's delegate if you use navigation controller. 43 | - Else assign it as your view controller's `transitioningDelegate`. 44 | 45 | ``` swift 46 | 47 | var transition: TransitionManager! 48 | 49 | override func viewDidLoad() { 50 | super.viewDidLoad() 51 | 52 | transition = TransitionManager (transitionAnimation: FadeTransitionAnimation()) 53 | navigationController?.delegate = transition 54 | } 55 | 56 | ``` 57 | 58 | 59 | Creating Transition Animations 60 | ----- 61 | 62 | 63 | Create a subclass of `TransitionManagerAnimation` 64 | 65 | ``` swift 66 | class FadeTransitionAnimation: TransitionManagerAnimation { 67 | 68 | } 69 | ``` 70 | 71 | `TransitionManagerAnimation` class implements `TransitionManagerDelegate` protocol. 72 | 73 | ##### TransitionManagerDelegate 74 | 75 | ``` swift 76 | 77 | protocol TransitionManagerDelegate { 78 | 79 | func transition ( 80 | container: UIView, 81 | fromViewController: UIViewController, 82 | toViewController: UIViewController, 83 | duration: NSTimeInterval, 84 | completion: ()->Void) 85 | 86 | var interactionTransitionController: UIPercentDrivenInteractiveTransition? { get set } 87 | } 88 | 89 | ``` 90 | 91 | For transition animation, we should override `transition` func and write our custom animation in it. 92 | 93 | ``` swift 94 | 95 | class FadeTransitionAnimation: TransitionManagerAnimation { 96 | 97 | override func transition ( 98 | container: UIView, 99 | fromViewController: UIViewController, 100 | toViewController: UIViewController, 101 | duration: NSTimeInterval, 102 | completion: ()->Void) { 103 | 104 | let fromView = fromViewController.view 105 | let toView = toViewController.view 106 | 107 | container.addSubview(toView) 108 | toView.alpha = 0 109 | 110 | UIView.animateWithDuration( 111 | duration, 112 | animations: { 113 | toView.alpha = 1 114 | }, 115 | completion: { finished in 116 | completion () 117 | }) 118 | } 119 | } 120 | 121 | ``` 122 | 123 | One important part is `completion()` must be called because the `TransitionManager` finishes transition after it gets called. 124 | 125 | 126 | ### Interaction Transition 127 | 128 | Create a `TransitionManagerAnimation` subclass and write an initilizer with `UINavigationController` parameter. 129 | 130 | Add its `view` a pan gesture 131 | 132 | ``` swift 133 | class LeftTransitionAnimation: TransitionManagerAnimation { 134 | 135 | var navigationController: UINavigationController! 136 | 137 | init (navigationController: UINavigationController) { 138 | super.init() 139 | 140 | self.navigationController = navigationController 141 | self.navigationController.view.addGestureRecognizer(UIPanGestureRecognizer (target: self, action: Selector("didPan:"))) 142 | } 143 | 144 | } 145 | ``` 146 | 147 | We will update `interactionTransitionController` variable in [`TransitionManagerDelegate`](#Delegate) in gesture handler. 148 | 149 | ``` swift 150 | func didPan (gesture: UIPanGestureRecognizer) { 151 | let percent = gesture.translationInView(gesture.view!).x / gesture.view!.bounds.size.width 152 | 153 | switch gesture.state { 154 | case .Began: 155 | interactionTransitionController = UIPercentDrivenInteractiveTransition() 156 | navigationController.popViewControllerAnimated(true) 157 | 158 | case .Changed: 159 | interactionTransitionController!.updateInteractiveTransition(percent) 160 | 161 | case .Ended: 162 | if percent > 0.5 { 163 | interactionTransitionController!.finishInteractiveTransition() 164 | } else { 165 | interactionTransitionController!.cancelInteractiveTransition() 166 | } 167 | interactionTransitionController = nil 168 | 169 | default: 170 | return 171 | } 172 | } 173 | ``` 174 | 175 | Interaction transition has 3 parts: 176 | * Init `interactionTransitionController` and either pop or push navigation controller when gesture (interaction) starts. 177 | * Calculate your `percent`s on gesture change and `updateInteractiveTransition:` with that percent 178 | * When gesture ended, decide if your transition complete or not and give information to your `interactionTransitionController` with `finishInteractiveTransition ()` and `cancelInteractiveTransition ()` 179 | 180 | 181 | ### Easier `TransitionManager` setup 182 | 183 | You can create a `TransitionManagerAnimation` container enum and give it all your animations 184 | 185 | ``` swift 186 | enum TransitionManagerAnimations { 187 | case Fade 188 | case Left 189 | } 190 | ``` 191 | 192 | Write a func that returns correct transition animation in enum 193 | 194 | ``` swift 195 | enum TransitionManagerAnimations { 196 | case Fade 197 | case Left (UINavigationController) 198 | 199 | func transitionAnimation () -> TransitionManagerAnimation { 200 | switch self { 201 | case .Fade: 202 | return FadeTransitionAnimation() 203 | 204 | case .Left (let nav): 205 | return LeftTransitionAnimation(navigationController: nav) 206 | 207 | default: 208 | return TransitionManagerAnimation() 209 | } 210 | } 211 | } 212 | ``` 213 | 214 | Extend `TransitionManager` and write a new init method like 215 | 216 | ``` swift 217 | 218 | extension TransitionManager { 219 | 220 | convenience init (transition: TransitionManagerAnimations) { 221 | self.init (transitionAnimation: transition.transitionAnimation()) 222 | } 223 | } 224 | 225 | ``` 226 | 227 | Now you can create `TransitionManager` in your view controller like 228 | 229 | ``` swift 230 | transition = TransitionManager (transition: .Left(navigationController!)) 231 | navigationController?.delegate = transition 232 | ``` 233 | DESC 234 | 235 | s.homepage = "https://github.com/cemolcay/TransitionManager" 236 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 237 | 238 | 239 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 240 | # 241 | # Licensing your code is important. See http://choosealicense.com for more info. 242 | # CocoaPods will detect a license file if there is a named LICENSE* 243 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 244 | # 245 | 246 | s.license = "MIT" 247 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 248 | 249 | 250 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 251 | # 252 | # Specify the authors of the library, with email addresses. Email addresses 253 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 254 | # accepts just a name if you'd rather not provide an email address. 255 | # 256 | # Specify a social_media_url where others can refer to, for example a twitter 257 | # profile URL. 258 | # 259 | 260 | s.author = { "cemolcay" => "ccemolcay@gmail.com" } 261 | # Or just: s.author = "cemolcay" 262 | # s.authors = { "cemolcay" => "ccemolcay@gmail.com" } 263 | s.social_media_url = "http://twitter.com/cemolcay" 264 | 265 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 266 | # 267 | # If this Pod runs only on iOS or OS X, then specify the platform and 268 | # the deployment target. You can optionally include the target after the platform. 269 | # 270 | 271 | s.platform = :ios 272 | s.platform = :ios, "8.0" 273 | 274 | # When using multiple platforms 275 | # s.ios.deployment_target = "5.0" 276 | # s.osx.deployment_target = "10.7" 277 | # s.watchos.deployment_target = "2.0" 278 | # s.tvos.deployment_target = "9.0" 279 | 280 | 281 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 282 | # 283 | # Specify the location from where the source should be retrieved. 284 | # Supports git, hg, bzr, svn and HTTP. 285 | # 286 | 287 | s.source = { :git => "https://github.com/cemolcay/TransitionManager.git", :tag => "#{s.version}" } 288 | 289 | 290 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 291 | # 292 | # CocoaPods is smart about how it includes source code. For source files 293 | # giving a folder will include any swift, h, m, mm, c & cpp files. 294 | # For header files it will include any header in the folder. 295 | # Not including the public_header_files will make all headers public. 296 | # 297 | 298 | s.source_files = "TransitionManager/Source/*.swift" 299 | # s.exclude_files = "Classes/Exclude" 300 | 301 | # s.public_header_files = "Classes/**/*.h" 302 | 303 | 304 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 305 | # 306 | # A list of resources included with the Pod. These are copied into the 307 | # target bundle with a build phase script. Anything else will be cleaned. 308 | # You can preserve files from being cleaned, please don't preserve 309 | # non-essential files like tests, examples and documentation. 310 | # 311 | 312 | # s.resource = "icon.png" 313 | # s.resources = "Resources/*.png" 314 | 315 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 316 | 317 | 318 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 319 | # 320 | # Link your library with frameworks, or libraries. Libraries do not include 321 | # the lib prefix of their name. 322 | # 323 | 324 | # s.framework = "SomeFramework" 325 | # s.frameworks = "SomeFramework", "AnotherFramework" 326 | 327 | # s.library = "iconv" 328 | # s.libraries = "iconv", "xml2" 329 | 330 | 331 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 332 | # 333 | # If your library depends on compiler flags you can set them in the xcconfig hash 334 | # where they will only apply to your library. If you depend on other Podspecs 335 | # you can include multiple dependencies to ensure it works. 336 | 337 | s.requires_arc = true 338 | 339 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 340 | # s.dependency "JSONKit", "~> 1.4" 341 | 342 | end 343 | -------------------------------------------------------------------------------- /TransitionManager.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B20D453B2164D518005C1F02 /* TransitionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B20D453A2164D518005C1F02 /* TransitionManager.swift */; }; 11 | B21AAA081BE401BC00A1DDFF /* AnimationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21AA9FA1BE401BC00A1DDFF /* AnimationHelper.swift */; }; 12 | B21AAA0A1BE401BC00A1DDFF /* TransitionAnimations.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21AA9FC1BE401BC00A1DDFF /* TransitionAnimations.swift */; }; 13 | B21AAA0B1BE401BC00A1DDFF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21AA9FD1BE401BC00A1DDFF /* ViewController.swift */; }; 14 | B21AAA0C1BE401BC00A1DDFF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21AA9FF1BE401BC00A1DDFF /* AppDelegate.swift */; }; 15 | B21AAA0D1BE401BC00A1DDFF /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = B21AAA001BE401BC00A1DDFF /* LaunchScreen.xib */; }; 16 | B21AAA0E1BE401BC00A1DDFF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B21AAA021BE401BC00A1DDFF /* Main.storyboard */; }; 17 | B21AAA0F1BE401BC00A1DDFF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B21AAA041BE401BC00A1DDFF /* Images.xcassets */; }; 18 | B2CF32C21A8B8119005A20FB /* TransitionManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2CF32C11A8B8119005A20FB /* TransitionManagerTests.swift */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | B2CF32BC1A8B8119005A20FB /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = B2CF329E1A8B8119005A20FB /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = B2CF32A51A8B8119005A20FB; 27 | remoteInfo = TransitionManager; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | B20D453A2164D518005C1F02 /* TransitionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransitionManager.swift; sourceTree = ""; }; 33 | B21AA9FA1BE401BC00A1DDFF /* AnimationHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationHelper.swift; sourceTree = ""; }; 34 | B21AA9FC1BE401BC00A1DDFF /* TransitionAnimations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransitionAnimations.swift; sourceTree = ""; }; 35 | B21AA9FD1BE401BC00A1DDFF /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 36 | B21AA9FF1BE401BC00A1DDFF /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | B21AAA011BE401BC00A1DDFF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 38 | B21AAA031BE401BC00A1DDFF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 39 | B21AAA041BE401BC00A1DDFF /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 40 | B21AAA051BE401BC00A1DDFF /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | B2CF32A61A8B8119005A20FB /* TransitionManager.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TransitionManager.app; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | B2CF32BB1A8B8119005A20FB /* TransitionManagerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TransitionManagerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | B2CF32C01A8B8119005A20FB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 44 | B2CF32C11A8B8119005A20FB /* TransitionManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransitionManagerTests.swift; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | B2CF32A31A8B8119005A20FB /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | B2CF32B81A8B8119005A20FB /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | B20D45392164D518005C1F02 /* Source */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | B20D453A2164D518005C1F02 /* TransitionManager.swift */, 69 | ); 70 | path = Source; 71 | sourceTree = ""; 72 | }; 73 | B21AA9F91BE401BC00A1DDFF /* Demo */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | B21AA9FC1BE401BC00A1DDFF /* TransitionAnimations.swift */, 77 | B21AA9FA1BE401BC00A1DDFF /* AnimationHelper.swift */, 78 | B21AA9FD1BE401BC00A1DDFF /* ViewController.swift */, 79 | ); 80 | path = Demo; 81 | sourceTree = ""; 82 | }; 83 | B21AA9FE1BE401BC00A1DDFF /* SupportingFiles */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | B21AA9FF1BE401BC00A1DDFF /* AppDelegate.swift */, 87 | B21AAA001BE401BC00A1DDFF /* LaunchScreen.xib */, 88 | B21AAA021BE401BC00A1DDFF /* Main.storyboard */, 89 | B21AAA041BE401BC00A1DDFF /* Images.xcassets */, 90 | B21AAA051BE401BC00A1DDFF /* Info.plist */, 91 | ); 92 | path = SupportingFiles; 93 | sourceTree = ""; 94 | }; 95 | B2CF329D1A8B8119005A20FB = { 96 | isa = PBXGroup; 97 | children = ( 98 | B2CF32A81A8B8119005A20FB /* TransitionManager */, 99 | B2CF32BE1A8B8119005A20FB /* TransitionManagerTests */, 100 | B2CF32A71A8B8119005A20FB /* Products */, 101 | ); 102 | sourceTree = ""; 103 | }; 104 | B2CF32A71A8B8119005A20FB /* Products */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | B2CF32A61A8B8119005A20FB /* TransitionManager.app */, 108 | B2CF32BB1A8B8119005A20FB /* TransitionManagerTests.xctest */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | B2CF32A81A8B8119005A20FB /* TransitionManager */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | B20D45392164D518005C1F02 /* Source */, 117 | B21AA9F91BE401BC00A1DDFF /* Demo */, 118 | B21AA9FE1BE401BC00A1DDFF /* SupportingFiles */, 119 | ); 120 | path = TransitionManager; 121 | sourceTree = ""; 122 | }; 123 | B2CF32BE1A8B8119005A20FB /* TransitionManagerTests */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | B2CF32C11A8B8119005A20FB /* TransitionManagerTests.swift */, 127 | B2CF32BF1A8B8119005A20FB /* Supporting Files */, 128 | ); 129 | path = TransitionManagerTests; 130 | sourceTree = ""; 131 | }; 132 | B2CF32BF1A8B8119005A20FB /* Supporting Files */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | B2CF32C01A8B8119005A20FB /* Info.plist */, 136 | ); 137 | name = "Supporting Files"; 138 | sourceTree = ""; 139 | }; 140 | /* End PBXGroup section */ 141 | 142 | /* Begin PBXNativeTarget section */ 143 | B2CF32A51A8B8119005A20FB /* TransitionManager */ = { 144 | isa = PBXNativeTarget; 145 | buildConfigurationList = B2CF32C51A8B8119005A20FB /* Build configuration list for PBXNativeTarget "TransitionManager" */; 146 | buildPhases = ( 147 | B2CF32A21A8B8119005A20FB /* Sources */, 148 | B2CF32A31A8B8119005A20FB /* Frameworks */, 149 | B2CF32A41A8B8119005A20FB /* Resources */, 150 | ); 151 | buildRules = ( 152 | ); 153 | dependencies = ( 154 | ); 155 | name = TransitionManager; 156 | productName = TransitionManager; 157 | productReference = B2CF32A61A8B8119005A20FB /* TransitionManager.app */; 158 | productType = "com.apple.product-type.application"; 159 | }; 160 | B2CF32BA1A8B8119005A20FB /* TransitionManagerTests */ = { 161 | isa = PBXNativeTarget; 162 | buildConfigurationList = B2CF32C81A8B8119005A20FB /* Build configuration list for PBXNativeTarget "TransitionManagerTests" */; 163 | buildPhases = ( 164 | B2CF32B71A8B8119005A20FB /* Sources */, 165 | B2CF32B81A8B8119005A20FB /* Frameworks */, 166 | B2CF32B91A8B8119005A20FB /* Resources */, 167 | ); 168 | buildRules = ( 169 | ); 170 | dependencies = ( 171 | B2CF32BD1A8B8119005A20FB /* PBXTargetDependency */, 172 | ); 173 | name = TransitionManagerTests; 174 | productName = TransitionManagerTests; 175 | productReference = B2CF32BB1A8B8119005A20FB /* TransitionManagerTests.xctest */; 176 | productType = "com.apple.product-type.bundle.unit-test"; 177 | }; 178 | /* End PBXNativeTarget section */ 179 | 180 | /* Begin PBXProject section */ 181 | B2CF329E1A8B8119005A20FB /* Project object */ = { 182 | isa = PBXProject; 183 | attributes = { 184 | LastSwiftUpdateCheck = 0710; 185 | LastUpgradeCheck = 1000; 186 | ORGANIZATIONNAME = "Cem Olcay"; 187 | TargetAttributes = { 188 | B2CF32A51A8B8119005A20FB = { 189 | CreatedOnToolsVersion = 6.1.1; 190 | DevelopmentTeam = 77Y3N48SNF; 191 | }; 192 | B2CF32BA1A8B8119005A20FB = { 193 | CreatedOnToolsVersion = 6.1.1; 194 | DevelopmentTeam = 77Y3N48SNF; 195 | TestTargetID = B2CF32A51A8B8119005A20FB; 196 | }; 197 | }; 198 | }; 199 | buildConfigurationList = B2CF32A11A8B8119005A20FB /* Build configuration list for PBXProject "TransitionManager" */; 200 | compatibilityVersion = "Xcode 3.2"; 201 | developmentRegion = English; 202 | hasScannedForEncodings = 0; 203 | knownRegions = ( 204 | en, 205 | Base, 206 | ); 207 | mainGroup = B2CF329D1A8B8119005A20FB; 208 | productRefGroup = B2CF32A71A8B8119005A20FB /* Products */; 209 | projectDirPath = ""; 210 | projectRoot = ""; 211 | targets = ( 212 | B2CF32A51A8B8119005A20FB /* TransitionManager */, 213 | B2CF32BA1A8B8119005A20FB /* TransitionManagerTests */, 214 | ); 215 | }; 216 | /* End PBXProject section */ 217 | 218 | /* Begin PBXResourcesBuildPhase section */ 219 | B2CF32A41A8B8119005A20FB /* Resources */ = { 220 | isa = PBXResourcesBuildPhase; 221 | buildActionMask = 2147483647; 222 | files = ( 223 | B21AAA0F1BE401BC00A1DDFF /* Images.xcassets in Resources */, 224 | B21AAA0D1BE401BC00A1DDFF /* LaunchScreen.xib in Resources */, 225 | B21AAA0E1BE401BC00A1DDFF /* Main.storyboard in Resources */, 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | }; 229 | B2CF32B91A8B8119005A20FB /* Resources */ = { 230 | isa = PBXResourcesBuildPhase; 231 | buildActionMask = 2147483647; 232 | files = ( 233 | ); 234 | runOnlyForDeploymentPostprocessing = 0; 235 | }; 236 | /* End PBXResourcesBuildPhase section */ 237 | 238 | /* Begin PBXSourcesBuildPhase section */ 239 | B2CF32A21A8B8119005A20FB /* Sources */ = { 240 | isa = PBXSourcesBuildPhase; 241 | buildActionMask = 2147483647; 242 | files = ( 243 | B20D453B2164D518005C1F02 /* TransitionManager.swift in Sources */, 244 | B21AAA081BE401BC00A1DDFF /* AnimationHelper.swift in Sources */, 245 | B21AAA0A1BE401BC00A1DDFF /* TransitionAnimations.swift in Sources */, 246 | B21AAA0B1BE401BC00A1DDFF /* ViewController.swift in Sources */, 247 | B21AAA0C1BE401BC00A1DDFF /* AppDelegate.swift in Sources */, 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | }; 251 | B2CF32B71A8B8119005A20FB /* Sources */ = { 252 | isa = PBXSourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | B2CF32C21A8B8119005A20FB /* TransitionManagerTests.swift in Sources */, 256 | ); 257 | runOnlyForDeploymentPostprocessing = 0; 258 | }; 259 | /* End PBXSourcesBuildPhase section */ 260 | 261 | /* Begin PBXTargetDependency section */ 262 | B2CF32BD1A8B8119005A20FB /* PBXTargetDependency */ = { 263 | isa = PBXTargetDependency; 264 | target = B2CF32A51A8B8119005A20FB /* TransitionManager */; 265 | targetProxy = B2CF32BC1A8B8119005A20FB /* PBXContainerItemProxy */; 266 | }; 267 | /* End PBXTargetDependency section */ 268 | 269 | /* Begin PBXVariantGroup section */ 270 | B21AAA001BE401BC00A1DDFF /* LaunchScreen.xib */ = { 271 | isa = PBXVariantGroup; 272 | children = ( 273 | B21AAA011BE401BC00A1DDFF /* Base */, 274 | ); 275 | name = LaunchScreen.xib; 276 | sourceTree = ""; 277 | }; 278 | B21AAA021BE401BC00A1DDFF /* Main.storyboard */ = { 279 | isa = PBXVariantGroup; 280 | children = ( 281 | B21AAA031BE401BC00A1DDFF /* Base */, 282 | ); 283 | name = Main.storyboard; 284 | sourceTree = ""; 285 | }; 286 | /* End PBXVariantGroup section */ 287 | 288 | /* Begin XCBuildConfiguration section */ 289 | B2CF32C31A8B8119005A20FB /* Debug */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | ALWAYS_SEARCH_USER_PATHS = NO; 293 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 294 | CLANG_CXX_LIBRARY = "libc++"; 295 | CLANG_ENABLE_MODULES = YES; 296 | CLANG_ENABLE_OBJC_ARC = YES; 297 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 298 | CLANG_WARN_BOOL_CONVERSION = YES; 299 | CLANG_WARN_COMMA = YES; 300 | CLANG_WARN_CONSTANT_CONVERSION = YES; 301 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 302 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 303 | CLANG_WARN_EMPTY_BODY = YES; 304 | CLANG_WARN_ENUM_CONVERSION = YES; 305 | CLANG_WARN_INFINITE_RECURSION = YES; 306 | CLANG_WARN_INT_CONVERSION = YES; 307 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 308 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 309 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 310 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 311 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 312 | CLANG_WARN_STRICT_PROTOTYPES = YES; 313 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 314 | CLANG_WARN_UNREACHABLE_CODE = YES; 315 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 316 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 317 | COPY_PHASE_STRIP = NO; 318 | ENABLE_STRICT_OBJC_MSGSEND = YES; 319 | ENABLE_TESTABILITY = YES; 320 | GCC_C_LANGUAGE_STANDARD = gnu99; 321 | GCC_DYNAMIC_NO_PIC = NO; 322 | GCC_NO_COMMON_BLOCKS = YES; 323 | GCC_OPTIMIZATION_LEVEL = 0; 324 | GCC_PREPROCESSOR_DEFINITIONS = ( 325 | "DEBUG=1", 326 | "$(inherited)", 327 | ); 328 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 329 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 330 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 331 | GCC_WARN_UNDECLARED_SELECTOR = YES; 332 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 333 | GCC_WARN_UNUSED_FUNCTION = YES; 334 | GCC_WARN_UNUSED_VARIABLE = YES; 335 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 336 | MTL_ENABLE_DEBUG_INFO = YES; 337 | ONLY_ACTIVE_ARCH = YES; 338 | SDKROOT = iphoneos; 339 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 340 | TARGETED_DEVICE_FAMILY = "1,2"; 341 | }; 342 | name = Debug; 343 | }; 344 | B2CF32C41A8B8119005A20FB /* Release */ = { 345 | isa = XCBuildConfiguration; 346 | buildSettings = { 347 | ALWAYS_SEARCH_USER_PATHS = NO; 348 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 349 | CLANG_CXX_LIBRARY = "libc++"; 350 | CLANG_ENABLE_MODULES = YES; 351 | CLANG_ENABLE_OBJC_ARC = YES; 352 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 353 | CLANG_WARN_BOOL_CONVERSION = YES; 354 | CLANG_WARN_COMMA = YES; 355 | CLANG_WARN_CONSTANT_CONVERSION = YES; 356 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 357 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 358 | CLANG_WARN_EMPTY_BODY = YES; 359 | CLANG_WARN_ENUM_CONVERSION = YES; 360 | CLANG_WARN_INFINITE_RECURSION = YES; 361 | CLANG_WARN_INT_CONVERSION = YES; 362 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 363 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 364 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 365 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 366 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 367 | CLANG_WARN_STRICT_PROTOTYPES = YES; 368 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 369 | CLANG_WARN_UNREACHABLE_CODE = YES; 370 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 371 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 372 | COPY_PHASE_STRIP = YES; 373 | ENABLE_NS_ASSERTIONS = NO; 374 | ENABLE_STRICT_OBJC_MSGSEND = YES; 375 | GCC_C_LANGUAGE_STANDARD = gnu99; 376 | GCC_NO_COMMON_BLOCKS = YES; 377 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 378 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 379 | GCC_WARN_UNDECLARED_SELECTOR = YES; 380 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 381 | GCC_WARN_UNUSED_FUNCTION = YES; 382 | GCC_WARN_UNUSED_VARIABLE = YES; 383 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 384 | MTL_ENABLE_DEBUG_INFO = NO; 385 | SDKROOT = iphoneos; 386 | SWIFT_COMPILATION_MODE = wholemodule; 387 | TARGETED_DEVICE_FAMILY = "1,2"; 388 | VALIDATE_PRODUCT = YES; 389 | }; 390 | name = Release; 391 | }; 392 | B2CF32C61A8B8119005A20FB /* Debug */ = { 393 | isa = XCBuildConfiguration; 394 | buildSettings = { 395 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 396 | DEVELOPMENT_TEAM = 77Y3N48SNF; 397 | INFOPLIST_FILE = "$(SRCROOT)/TransitionManager/SupportingFiles/Info.plist"; 398 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 399 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 400 | PRODUCT_BUNDLE_IDENTIFIER = "com.questa.$(PRODUCT_NAME:rfc1034identifier)"; 401 | PRODUCT_NAME = "$(TARGET_NAME)"; 402 | SWIFT_VERSION = 4.2; 403 | }; 404 | name = Debug; 405 | }; 406 | B2CF32C71A8B8119005A20FB /* Release */ = { 407 | isa = XCBuildConfiguration; 408 | buildSettings = { 409 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 410 | DEVELOPMENT_TEAM = 77Y3N48SNF; 411 | INFOPLIST_FILE = "$(SRCROOT)/TransitionManager/SupportingFiles/Info.plist"; 412 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 413 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 414 | PRODUCT_BUNDLE_IDENTIFIER = "com.questa.$(PRODUCT_NAME:rfc1034identifier)"; 415 | PRODUCT_NAME = "$(TARGET_NAME)"; 416 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 417 | SWIFT_VERSION = 4.2; 418 | }; 419 | name = Release; 420 | }; 421 | B2CF32C91A8B8119005A20FB /* Debug */ = { 422 | isa = XCBuildConfiguration; 423 | buildSettings = { 424 | BUNDLE_LOADER = "$(TEST_HOST)"; 425 | DEVELOPMENT_TEAM = 77Y3N48SNF; 426 | FRAMEWORK_SEARCH_PATHS = ( 427 | "$(SDKROOT)/Developer/Library/Frameworks", 428 | "$(inherited)", 429 | ); 430 | GCC_PREPROCESSOR_DEFINITIONS = ( 431 | "DEBUG=1", 432 | "$(inherited)", 433 | ); 434 | INFOPLIST_FILE = TransitionManagerTests/Info.plist; 435 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 436 | PRODUCT_BUNDLE_IDENTIFIER = "com.questa.$(PRODUCT_NAME:rfc1034identifier)"; 437 | PRODUCT_NAME = "$(TARGET_NAME)"; 438 | SWIFT_VERSION = 4.2; 439 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TransitionManager.app/TransitionManager"; 440 | }; 441 | name = Debug; 442 | }; 443 | B2CF32CA1A8B8119005A20FB /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | BUNDLE_LOADER = "$(TEST_HOST)"; 447 | DEVELOPMENT_TEAM = 77Y3N48SNF; 448 | FRAMEWORK_SEARCH_PATHS = ( 449 | "$(SDKROOT)/Developer/Library/Frameworks", 450 | "$(inherited)", 451 | ); 452 | INFOPLIST_FILE = TransitionManagerTests/Info.plist; 453 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 454 | PRODUCT_BUNDLE_IDENTIFIER = "com.questa.$(PRODUCT_NAME:rfc1034identifier)"; 455 | PRODUCT_NAME = "$(TARGET_NAME)"; 456 | SWIFT_VERSION = 4.2; 457 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TransitionManager.app/TransitionManager"; 458 | }; 459 | name = Release; 460 | }; 461 | /* End XCBuildConfiguration section */ 462 | 463 | /* Begin XCConfigurationList section */ 464 | B2CF32A11A8B8119005A20FB /* Build configuration list for PBXProject "TransitionManager" */ = { 465 | isa = XCConfigurationList; 466 | buildConfigurations = ( 467 | B2CF32C31A8B8119005A20FB /* Debug */, 468 | B2CF32C41A8B8119005A20FB /* Release */, 469 | ); 470 | defaultConfigurationIsVisible = 0; 471 | defaultConfigurationName = Release; 472 | }; 473 | B2CF32C51A8B8119005A20FB /* Build configuration list for PBXNativeTarget "TransitionManager" */ = { 474 | isa = XCConfigurationList; 475 | buildConfigurations = ( 476 | B2CF32C61A8B8119005A20FB /* Debug */, 477 | B2CF32C71A8B8119005A20FB /* Release */, 478 | ); 479 | defaultConfigurationIsVisible = 0; 480 | defaultConfigurationName = Release; 481 | }; 482 | B2CF32C81A8B8119005A20FB /* Build configuration list for PBXNativeTarget "TransitionManagerTests" */ = { 483 | isa = XCConfigurationList; 484 | buildConfigurations = ( 485 | B2CF32C91A8B8119005A20FB /* Debug */, 486 | B2CF32CA1A8B8119005A20FB /* Release */, 487 | ); 488 | defaultConfigurationIsVisible = 0; 489 | defaultConfigurationName = Release; 490 | }; 491 | /* End XCConfigurationList section */ 492 | }; 493 | rootObject = B2CF329E1A8B8119005A20FB /* Project object */; 494 | } 495 | -------------------------------------------------------------------------------- /TransitionManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TransitionManager.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TransitionManager.xcodeproj/project.xcworkspace/xcshareddata/TransitionManager.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 3F77E847-AE96-4F06-88F1-E9D846795332 9 | IDESourceControlProjectName 10 | TransitionManager 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 57B26A0AF13FCA0F7824CDF8D62DEA763E9BC3F7 14 | https://github.com/cemolcay/TransitionManager.git 15 | 16 | IDESourceControlProjectPath 17 | TransitionManager.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 57B26A0AF13FCA0F7824CDF8D62DEA763E9BC3F7 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/cemolcay/TransitionManager.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 57B26A0AF13FCA0F7824CDF8D62DEA763E9BC3F7 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 57B26A0AF13FCA0F7824CDF8D62DEA763E9BC3F7 36 | IDESourceControlWCCName 37 | TransitionManager 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /TransitionManager.xcodeproj/project.xcworkspace/xcuserdata/Cem.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cemolcay/TransitionManager/ea3bb040e8a319b72776261467257108f6d3b4a0/TransitionManager.xcodeproj/project.xcworkspace/xcuserdata/Cem.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /TransitionManager.xcodeproj/xcuserdata/cem.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /TransitionManager.xcodeproj/xcuserdata/cem.xcuserdatad/xcschemes/TransitionManager.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /TransitionManager.xcodeproj/xcuserdata/cem.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TransitionManager.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | B2CF32A51A8B8119005A20FB 16 | 17 | primary 18 | 19 | 20 | B2CF32BA1A8B8119005A20FB 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /TransitionManager/Demo/AnimationHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnimationHelper.swift 3 | // TransitionManager 4 | // 5 | // Created by Cem Olcay on 12/02/15. 6 | // Copyright (c) 2015 Cem Olcay. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // MARK: Frame Extensions 12 | 13 | extension UIView { 14 | 15 | var x: CGFloat { 16 | get { 17 | return self.frame.origin.x 18 | } set (value) { 19 | self.frame = CGRect (x: value, y: self.y, width: self.w, height: self.h) 20 | } 21 | } 22 | 23 | var y: CGFloat { 24 | get { 25 | return self.frame.origin.y 26 | } set (value) { 27 | self.frame = CGRect (x: self.x, y: value, width: self.w, height: self.h) 28 | } 29 | } 30 | 31 | var w: CGFloat { 32 | get { 33 | return self.frame.size.width 34 | } set (value) { 35 | self.frame = CGRect (x: self.x, y: self.y, width: value, height: self.h) 36 | } 37 | } 38 | 39 | var h: CGFloat { 40 | get { 41 | return self.frame.size.height 42 | } set (value) { 43 | self.frame = CGRect (x: self.x, y: self.y, width: self.w, height: value) 44 | } 45 | } 46 | 47 | var left: CGFloat { 48 | get { 49 | return self.x 50 | } set (value) { 51 | self.x = value 52 | } 53 | } 54 | 55 | var right: CGFloat { 56 | get { 57 | return self.x + self.w 58 | } set (value) { 59 | self.x = value - self.w 60 | } 61 | } 62 | 63 | var top: CGFloat { 64 | get { 65 | return self.y 66 | } set (value) { 67 | self.y = value 68 | } 69 | } 70 | 71 | var bottom: CGFloat { 72 | get { 73 | return self.y + self.h 74 | } set (value) { 75 | self.y = value - self.h 76 | } 77 | } 78 | 79 | var position: CGPoint { 80 | get { 81 | return self.frame.origin 82 | } set (value) { 83 | self.frame = CGRect (origin: value, size: self.frame.size) 84 | } 85 | } 86 | 87 | var size: CGSize { 88 | get { 89 | return self.frame.size 90 | } set (value) { 91 | self.frame = CGRect (origin: self.frame.origin, size: value) 92 | } 93 | } 94 | 95 | func leftWithOffset (offset: CGFloat) -> CGFloat { 96 | return self.left - offset 97 | } 98 | 99 | func rightWithOffset (offset: CGFloat) -> CGFloat { 100 | return self.right + offset 101 | } 102 | 103 | func topWithOffset (offset: CGFloat) -> CGFloat { 104 | return self.top - offset 105 | } 106 | 107 | func bottomWithOffset (offset: CGFloat) -> CGFloat { 108 | return self.bottom + offset 109 | } 110 | } 111 | 112 | // MARK: Transform Extensions 113 | 114 | func degreesToRadians (angle: CGFloat) -> CGFloat { 115 | return (.pi * angle) / 180.0 116 | } 117 | 118 | extension UIView { 119 | 120 | func setRotationX (x: CGFloat) { 121 | var transform = CATransform3DIdentity 122 | transform.m34 = 1.0 / -1000.0 123 | transform = CATransform3DRotate(transform, degreesToRadians(angle: x), 1.0, 0.0, 0.0) 124 | self.layer.transform = transform 125 | } 126 | 127 | func setRotationY (y: CGFloat) { 128 | var transform = CATransform3DIdentity 129 | transform.m34 = 1.0 / -1000.0 130 | transform = CATransform3DRotate(transform, degreesToRadians(angle: y), 0.0, 1.0, 0.0) 131 | self.layer.transform = transform 132 | } 133 | 134 | func setRotationZ (z: CGFloat) { 135 | var transform = CATransform3DIdentity 136 | transform.m34 = 1.0 / -1000.0 137 | transform = CATransform3DRotate(transform, degreesToRadians(angle: z), 0.0, 0.0, 1.0) 138 | self.layer.transform = transform 139 | } 140 | 141 | func setRotation ( 142 | x: CGFloat, 143 | y: CGFloat, 144 | z: CGFloat) { 145 | var transform = CATransform3DIdentity 146 | transform.m34 = 1.0 / -1000.0 147 | transform = CATransform3DRotate(transform, degreesToRadians(angle: x), 1.0, 0.0, 0.0) 148 | transform = CATransform3DRotate(transform, degreesToRadians(angle: y), 0.0, 1.0, 0.0) 149 | transform = CATransform3DRotate(transform, degreesToRadians(angle: z), 0.0, 0.0, 1.0) 150 | self.layer.transform = transform 151 | } 152 | 153 | func setScale ( 154 | x: CGFloat, 155 | y: CGFloat) { 156 | var transform = CATransform3DIdentity 157 | transform.m34 = 1.0 / -1000.0 158 | transform = CATransform3DScale(transform, x, y, 1) 159 | self.layer.transform = transform 160 | } 161 | } 162 | 163 | // MARK: Animation Extensions 164 | 165 | let UIViewAnimationDuration: TimeInterval = 1 166 | let UIViewAnimationSpringDamping: CGFloat = 0.5 167 | let UIViewAnimationSpringVelocity: CGFloat = 0.5 168 | 169 | extension UIView { 170 | 171 | func spring ( 172 | duration: TimeInterval = UIViewAnimationDuration, 173 | animations: @escaping (() -> Void), 174 | completion: ((Bool) -> Void)? = nil) { 175 | UIView.animate( 176 | withDuration: duration, 177 | delay: 0, 178 | usingSpringWithDamping: UIViewAnimationSpringDamping, 179 | initialSpringVelocity: UIViewAnimationSpringVelocity, 180 | options: [UIView.AnimationOptions.allowAnimatedContent], 181 | animations: animations, 182 | completion: completion) 183 | } 184 | 185 | func animate ( 186 | duration: TimeInterval, 187 | animations: @escaping (() -> Void), 188 | completion: ((Bool) -> Void)? = nil) { 189 | UIView.animate( 190 | withDuration: duration, 191 | animations: animations, 192 | completion: completion) 193 | } 194 | 195 | func animate ( 196 | animations: @escaping (() -> Void), 197 | completion: ((Bool) -> Void)? = nil) { 198 | animate( 199 | duration: UIViewAnimationDuration, 200 | animations: animations, 201 | completion: completion) 202 | } 203 | 204 | func pop () { 205 | setScale(x: 1.1, y: 1.1) 206 | spring( 207 | duration: 0.2, 208 | animations: { [unowned self] in 209 | self.setScale(x: 1, y: 1) 210 | }) 211 | } 212 | } 213 | 214 | // MARK: Render Extensions 215 | 216 | extension UIView { 217 | func toImage () -> UIImage { 218 | UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0.0) 219 | drawHierarchy(in: bounds, afterScreenUpdates: false) 220 | let img = UIGraphicsGetImageFromCurrentImageContext() 221 | UIGraphicsEndImageContext() 222 | return img ?? UIImage() 223 | } 224 | } 225 | 226 | -------------------------------------------------------------------------------- /TransitionManager/Demo/TransitionAnimations.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TransitionAnimations.swift 3 | // TransitionManager 4 | // 5 | // Created by Cem Olcay on 12/02/15. 6 | // Copyright (c) 2015 Cem Olcay. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // MARK: TransitionManager Extension 12 | 13 | enum TransitionManagerAnimations { 14 | case fade 15 | case pull 16 | 17 | func transitionAnimation () -> TransitionManagerAnimation { 18 | switch self { 19 | case .fade: 20 | return FadeTransitionAnimation() 21 | case .pull: 22 | return PullTransitionAnimation() 23 | } 24 | } 25 | } 26 | 27 | extension TransitionManager { 28 | convenience init (transition: TransitionManagerAnimations) { 29 | self.init (transitionAnimation: transition.transitionAnimation()) 30 | } 31 | } 32 | 33 | // MARK: - Fade Transition 34 | 35 | class FadeTransitionAnimation: TransitionManagerAnimation { 36 | override func transition( 37 | container: UIView, 38 | fromViewController: UIViewController, 39 | toViewController: UIViewController, 40 | isDismissing: Bool, 41 | duration: TimeInterval, 42 | completion: @escaping () -> Void) { 43 | if isDismissing { 44 | closeAnimation( 45 | container: container, 46 | fromViewController: fromViewController, 47 | toViewController: toViewController, 48 | duration: duration, 49 | completion: completion) 50 | } else { 51 | openAnimation( 52 | container: container, 53 | fromViewController: fromViewController, 54 | toViewController: toViewController, 55 | duration: duration, 56 | completion: completion) 57 | } 58 | } 59 | 60 | func openAnimation ( 61 | container: UIView, 62 | fromViewController: UIViewController, 63 | toViewController: UIViewController, 64 | duration: TimeInterval, 65 | completion: @escaping () -> Void) { 66 | 67 | toViewController.view.alpha = 0 68 | container.addSubview(toViewController.view) 69 | 70 | UIView.animate( 71 | withDuration: duration, 72 | animations: { 73 | toViewController.view.alpha = 1 74 | }, 75 | completion: { finished in 76 | fromViewController.view.alpha = 1 77 | completion() 78 | }) 79 | } 80 | 81 | func closeAnimation ( 82 | container: UIView, 83 | fromViewController: UIViewController, 84 | toViewController: UIViewController, 85 | duration: TimeInterval, 86 | completion: @escaping () -> Void) { 87 | 88 | container.addSubview(toViewController.view) 89 | container.bringSubviewToFront(fromViewController.view) 90 | 91 | UIView.animate( 92 | withDuration: duration, 93 | animations: { 94 | fromViewController.view.alpha = 0 95 | }, 96 | completion: { finished in 97 | completion() 98 | }) 99 | } 100 | } 101 | 102 | // MARK: Pull Transition 103 | 104 | class PullTransitionAnimation: TransitionManagerAnimation { 105 | private weak var panningViewController: UIViewController? 106 | 107 | override func transition( 108 | container: UIView, 109 | fromViewController: UIViewController, 110 | toViewController: UIViewController, 111 | isDismissing: Bool, 112 | duration: TimeInterval, 113 | completion: @escaping () -> Void) { 114 | if isDismissing { 115 | closeAnimation( 116 | container: container, 117 | fromViewController: fromViewController, 118 | toViewController: toViewController, 119 | duration: duration, 120 | completion: completion) 121 | } else { 122 | openAnimation( 123 | container: container, 124 | fromViewController: fromViewController, 125 | toViewController: toViewController, 126 | duration: duration, 127 | completion: completion) 128 | } 129 | } 130 | 131 | func openAnimation ( 132 | container: UIView, 133 | fromViewController: UIViewController, 134 | toViewController: UIViewController, 135 | duration: TimeInterval, 136 | completion: @escaping () -> Void) { 137 | 138 | container.addSubview(toViewController.view) 139 | toViewController.view.top = fromViewController.view.bottom 140 | toViewController.view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan(pan:)))) 141 | panningViewController = toViewController 142 | 143 | UIView.animate( 144 | withDuration: duration, 145 | animations: { 146 | toViewController.view.top = 0 147 | }, 148 | completion: { finished in 149 | completion() 150 | }) 151 | } 152 | 153 | func closeAnimation ( 154 | container: UIView, 155 | fromViewController: UIViewController, 156 | toViewController: UIViewController, 157 | duration: TimeInterval, 158 | completion: @escaping () -> Void) { 159 | 160 | container.addSubview(toViewController.view) 161 | container.bringSubviewToFront(fromViewController.view) 162 | 163 | UIView.animate( 164 | withDuration: duration, 165 | animations: { 166 | fromViewController.view.top = toViewController.view.bottom 167 | }, 168 | completion: { finished in 169 | completion() 170 | }) 171 | } 172 | 173 | @objc func handlePan(pan: UIPanGestureRecognizer) { 174 | let percent = pan.translation(in: pan.view!).y / pan.view!.bounds.size.height 175 | switch pan.state { 176 | case .began: 177 | interactionTransitionController = UIPercentDrivenInteractiveTransition() 178 | panningViewController?.dismiss(animated: true, completion: { 179 | self.interactionTransitionController?.finish() 180 | }) 181 | case .changed: 182 | interactionTransitionController!.update(percent) 183 | case .ended: 184 | if percent > 0.5 { 185 | interactionTransitionController!.finish() 186 | panningViewController = nil 187 | } else { 188 | interactionTransitionController!.cancel() 189 | } 190 | interactionTransitionController = nil 191 | default: 192 | return 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /TransitionManager/Demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // TransitionManager 4 | // 5 | // Created by Cem Olcay on 11/02/15. 6 | // Copyright (c) 2015 Cem Olcay. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class DemoButton: UIButton { 12 | private var action: (() -> Void)! 13 | 14 | init(title: String, action: @escaping () -> Void) { 15 | super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 50)) 16 | self.action = action 17 | setTitle(title, for: .normal) 18 | setTitleColor(UIColor(red: 230.0/255.0, green: 172.0/255.0, blue: 39.0/255.0, alpha: 1), for: .normal) 19 | titleLabel?.font = UIFont(name: "AvenirNext-DemiBold", size: 20) 20 | layer.borderWidth = 3 21 | layer.borderColor = UIColor(red: 191.0/255.0, green: 77.0/255.0, blue: 40.0/255.0, alpha: 1).cgColor 22 | layer.cornerRadius = 25 23 | addTarget(self, action: #selector(actionHandler(sender:)), for: .touchUpInside) 24 | } 25 | 26 | required init?(coder aDecoder: NSCoder) { 27 | super.init(coder: aDecoder) 28 | } 29 | 30 | @objc func actionHandler(sender: AnyObject) { 31 | action() 32 | } 33 | } 34 | 35 | class ModalViewController: UIViewController { 36 | override func viewDidLoad() { 37 | super.viewDidLoad() 38 | let button = DemoButton(title: "Back", action: { 39 | self.dismiss(animated: true, completion: nil) 40 | }) 41 | button.center.x = view.center.x 42 | button.y = 50 43 | view.addSubview(button) 44 | } 45 | } 46 | 47 | class ViewController: UIViewController { 48 | let transitionManager = TransitionManager(transition: .pull) 49 | 50 | override func viewDidLoad() { 51 | super.viewDidLoad() 52 | // setup transitioning 53 | transitioningDelegate = transitionManager 54 | 55 | // setup view 56 | let button = DemoButton(title: "Next", action: { 57 | self.performSegue(withIdentifier: "modal", sender: nil) 58 | }) 59 | button.center.x = view.center.x 60 | button.y = 50 61 | view.addSubview(button) 62 | } 63 | 64 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 65 | segue.destination.transitioningDelegate = transitionManager 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /TransitionManager/Source/TransitionManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TransitionManager.swift 3 | // Transition 4 | // 5 | // Created by Cem Olcay on 12/02/15. 6 | // Copyright (c) 2015 Cem Olcay. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol TransitionManagerDelegate { 12 | /// Transition animation method implementation 13 | func transition( 14 | container: UIView, 15 | fromViewController: UIViewController, 16 | toViewController: UIViewController, 17 | isDismissing: Bool, 18 | duration: TimeInterval, 19 | completion: @escaping () -> Void) 20 | 21 | /// Interactive transitions, 22 | /// update percent in gesture handler 23 | var interactionTransitionController: UIPercentDrivenInteractiveTransition? { get set } 24 | } 25 | 26 | open class TransitionManagerAnimation: NSObject, TransitionManagerDelegate { 27 | 28 | // MARK: TransitionManagerDelegate 29 | 30 | open func transition( 31 | container: UIView, 32 | fromViewController: UIViewController, 33 | toViewController: UIViewController, 34 | isDismissing: Bool, 35 | duration: TimeInterval, 36 | completion: @escaping () -> Void) { 37 | completion() 38 | } 39 | 40 | private var _interactionTransitionController: UIPercentDrivenInteractiveTransition? = nil 41 | open var interactionTransitionController: UIPercentDrivenInteractiveTransition? { 42 | get { 43 | return _interactionTransitionController 44 | } set { 45 | _interactionTransitionController = newValue 46 | } 47 | } 48 | } 49 | 50 | public class TransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate, UINavigationControllerDelegate { 51 | 52 | // MARK: Properties 53 | 54 | private var transitionAnimation: TransitionManagerAnimation! 55 | private var isDismissing: Bool = false 56 | private var duration: TimeInterval = 0.30 57 | 58 | // MARK: Lifecycle 59 | 60 | public init(transitionAnimation: TransitionManagerAnimation) { 61 | self.transitionAnimation = transitionAnimation 62 | } 63 | 64 | // MARK: UIViewControllerAnimatedTransitioning 65 | 66 | public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 67 | let container = transitionContext.containerView 68 | let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) 69 | let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) 70 | transitionAnimation.transition( 71 | container: container, 72 | fromViewController: fromViewController!, 73 | toViewController: toViewController!, 74 | isDismissing: isDismissing, 75 | duration: transitionDuration(using: transitionContext), 76 | completion: { 77 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 78 | }) 79 | } 80 | 81 | public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 82 | return duration 83 | } 84 | 85 | // MARK: UIViewControllerTransitioningDelegate 86 | 87 | public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 88 | isDismissing = false 89 | return self 90 | } 91 | 92 | public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 93 | isDismissing = true 94 | return self 95 | } 96 | 97 | public func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 98 | isDismissing = false 99 | return transitionAnimation.interactionTransitionController 100 | } 101 | 102 | public func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 103 | isDismissing = true 104 | return transitionAnimation.interactionTransitionController 105 | } 106 | 107 | // MARK: UINavigationControllerDelegate 108 | 109 | public func navigationController( 110 | _ navigationController: UINavigationController, 111 | animationControllerFor operation: UINavigationController.Operation, 112 | from fromVC: UIViewController, 113 | to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { 114 | if operation == .pop { 115 | isDismissing = true 116 | } else { 117 | isDismissing = false 118 | } 119 | return self 120 | } 121 | 122 | public func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 123 | return transitionAnimation.interactionTransitionController 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /TransitionManager/SupportingFiles/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // TransitionManager 4 | // 5 | // Created by Cem Olcay on 11/02/15. 6 | // Copyright (c) 2015 Cem Olcay. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { 17 | // Override point for customization after application launch. 18 | return true 19 | } 20 | 21 | func applicationWillResignActive(_ application: UIApplication) { 22 | 23 | } 24 | 25 | func applicationDidEnterBackground(_ application: UIApplication) { 26 | 27 | } 28 | 29 | func applicationWillEnterForeground(_ application: UIApplication) { 30 | 31 | } 32 | 33 | func applicationDidBecomeActive(_ application: UIApplication) { 34 | 35 | } 36 | 37 | func applicationWillTerminate(_ application: UIApplication) { 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /TransitionManager/SupportingFiles/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /TransitionManager/SupportingFiles/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /TransitionManager/SupportingFiles/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /TransitionManager/SupportingFiles/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIStatusBarStyle 34 | UIStatusBarStyleLightContent 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | UIViewControllerBasedStatusBarAppearance 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /TransitionManagerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /TransitionManagerTests/TransitionManagerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TransitionManagerTests.swift 3 | // TransitionManagerTests 4 | // 5 | // Created by Cem Olcay on 11/02/15. 6 | // Copyright (c) 2015 Cem Olcay. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class TransitionManagerTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | } 36 | --------------------------------------------------------------------------------