A library of custom iOS View Controller Animations and Interactions written in Swift.
Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.
You can install Carthage with Homebrew using the following commands:
brew update
brew install carthage
To integrate Shift into your Xcode project using Carthage, specify it in your Cartfile:
github "raizlabs/shift"
CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects.
To integrate Shift into your Xcode project using CocoaPods, specify it in your Podfile
:
pod 'Shift'
First, make sure you import the Shift module: import Shift
.
The rest is easy. If you are pushing a view controller to the navigation stack, follow these three steps:
- Set your navigation controller's delegate :
navigationController?.delegate = self
- Store the transition on your view controller:
var currentTransition: UIViewControllerAnimatedTransitioning?
- Extend your view controller to implement
UINavigationControllerDelegateTransitioning
. In your implementation, make sure to set thecurrentTransition
:
extension ViewController: UINavigationControllerDelegate {
func navigationController(navigationController: UINavigationController,
animationControllerForOperation operation: UINavigationControllerOperation,
fromViewController fromVC: UIViewController,
toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if (operation == .Push && fromVC == self) {
/*
* set currentTransition here
*/
}
else if (operation == .Pop && toVC == self) {
}
return currentTransition
}
}
SplitTransition
exposes 5 key properties:
screenshotScope
- (optional, defaults to.View
) - determines whether top and bottom views are sourced from container view or entire windowsplitLocation
(optional, defaults to0.0
) - y coordinate where the top and bottom views parttransitionDuration
(optional, defaults to1.0
) - duration (in seconds) of the transition animationtransitionDelay
(optional, defaults to0.0
) - delay (in seconds) before the start of the transition animationtransitionType
(optional, defaults to.Push
) -.Push
,.Pop
, or.Interactive
. SettingtransitionType
to.Interactive
will allow users to control the progress of the transition with a drag gesture.
Set these properties in your implementation of UINavigationControllerDelegateTransitioning
:
func navigationController(navigationController: UINavigationController,
animationControllerForOperation operation: UINavigationControllerOperation,
fromViewController fromVC: UIViewController,
toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if (operation == .Push && fromVC == self) {
let splitTransition = SplitTransitionController()
splitTransition.transitionDuration = 2.0
splitTransition.transitionType = .Push
splitTransition.splitLocation = currentCell != nil ? CGRectGetMidY(currentCell!.frame) : CGRectGetMidY(view.frame)
currentTransition = splitTransition
}
else if (operation == .Pop && toVC == self) {
currentTransition?.transitionType = .Pop
}
return currentTransition
}
Using SplitTransition
to present a view controller modally is simple. For the presented view controller, set modalPresentationStyle
to .Custom
. For the SplitTransition
, set transitionType
to .Presentation
, passing a presenting view controller and a presented view controller into the constructor. In addition, set your presented view controller's transitioningDelegate
to the newly created SplitTransition
.
// Configure destination view controller
let destinationViewController = UIViewController()
destinationViewController.modalPresentationStyle = .Custom
// Configure transition
let currentTransition = SplitTransition()
currentTransition?.transitionType = .Presentation(self, destinationViewController)
// Set transitioning delegate on destination view controller
destinationViewController.transitioningDelegate = currentTransition
Lastly, in presentViewController
's completion handler set transitionType
to .Dismiss
, again passing in a presented view controller and a presenting view controller:
presentViewController(destinationViewController, animated: true) { [weak self] () -> Void in
guard let vc = self,
presentedVC = self?.presentedViewController else {
debugPrint("SplitTransitionAnimatedPresentDismissViewControllerViewController has been deallocated")
return
}
// After presentation has finished, update transitionType on currentTransition
vc.currentTransition?.transitionType = .Dismissal(presentedVC, vc)
}
ZoomPushTransition
exposes 2 key properties:
transitionTime
- duration (in seconds) of the transitionscaleChangePct
- a transform which scales the destination view controller's view by `(sx, sy)' at the start of the transition
Set these properties in your view controller's implementation of UINavigationControllerDelegate
:
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let zoomPushTransition = ZoomPushTransition()
zoomPushTransition.transitionTime = 0.35
zoomPushTransition.scaleChangePct = 0.33
return zoomPushTransition
}