I am using a UISplitViewController
, with a MasterViewController
and DetailViewController
, without UINavigationController
s.
Currenly the segue animation for master->detail, triggered by
performSegueWithIdentifier("showDetail", sender: self)
consists in the DetailViewController
showing up from the bottom upwards.
How can I make that animation showing left-wards?
Embed your view controllers in UINavigationControllers.
Per the SplitViewController template:
On smaller devices it's going to have to use the Master's navigationController.
Furthermore this question has been answered here and here and here
More from the View Controller Programming Guide:
There are two ways to display a view controller onscreen: embed it in a container view controller or present it. Container view controllers provide an app’s primary navigation….
In storyboards it's not that difficult to embed something in a navigation controller. Click on the view controller you want to embed, then Editor->embed in->navigation controller.
I've recently needed to have more control of how the segues are being performed, so I made my custom segue classes which all perform the transition in different directions. Here's one of the implementations:
Swift 2.x
override func perform() {
//credits to http://www.appcoda.com/custom-segue-animations/
let firstClassView = self.sourceViewController.view
let secondClassView = self.destinationViewController.view
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
secondClassView.frame = CGRectMake(screenWidth, 0, screenWidth, screenHeight)
if let window = UIApplication.sharedApplication().keyWindow {
window.insertSubview(secondClassView, aboveSubview: firstClassView)
UIView.animateWithDuration(0.4, animations: { () -> Void in
firstClassView.frame = CGRectOffset(firstClassView.frame, -screenWidth, 0)
secondClassView.frame = CGRectOffset(secondClassView.frame, -screenWidth, 0)
}) {(Finished) -> Void in
self.sourceViewController.navigationController?.pushViewController(self.destinationViewController, animated: false)
}
}
}
This one will have a "right to left" transition. You can modify this function for your needs by simply changing the initial and ending positions of the source and destination view controller.
Also don't forget that you need to mark your segue as "custom segue", and to assign the new class to it.
UPDATE: Added Swift 3 version
Swift 3
override func perform() {
//credits to http://www.appcoda.com/custom-segue-animations/
let firstClassView = self.source.view
let secondClassView = self.destination.view
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
secondClassView?.frame = CGRect(x: screenWidth, y: 0, width: screenWidth, height: screenHeight)
if let window = UIApplication.shared.keyWindow {
window.insertSubview(secondClassView!, aboveSubview: firstClassView!)
UIView.animate(withDuration: 0.4, animations: { () -> Void in
firstClassView?.frame = (firstClassView?.frame.offsetBy(dx: -screenWidth, dy: 0))!
secondClassView?.frame = (secondClassView?.frame.offsetBy(dx: -screenWidth, dy: 0))!
}, completion: {(Finished) -> Void in
self.source.navigationController?.pushViewController(self.destination, animated: false)
})
}
}
--Swift 3.0--
Armin's solution adapted for swift 3. New -> File -> Cocoa Touch Class -> Class: ... (Subclass: UIStoryboardSegue).
import UIKit
class SlideHorSegue: UIStoryboardSegue {
override func perform() {
//credits to http://www.appcoda.com/custom-segue-animations/
let firstClassView = self.source.view
let secondClassView = self.destination.view
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
secondClassView?.frame = CGRect(x: screenWidth, y: 0, width: screenWidth, height: screenHeight)
if let window = UIApplication.shared.keyWindow {
window.insertSubview(secondClassView!, aboveSubview: firstClassView!)
UIView.animate(withDuration: 0.4, animations: { () -> Void in
firstClassView?.frame = (firstClassView?.frame)!.offsetBy(dx: -screenWidth, dy: 0)
secondClassView?.frame = (secondClassView?.frame)!.offsetBy(dx: -screenWidth, dy: 0)
}) {(Finished) -> Void in
self.source.navigationController?.pushViewController(self.destination, animated: false)
}
}
}
}
In storyboard: mark your segue as "custom segue", and to assign the new class to it.
Note: If you have a UIScrollView in your detailesVC, this won't work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With