Reputation: 255
I am trying to set up a custom segue from a view controller that is embedded in a navigation controller. When I use a show segue, everything is fine, the navigation bar remains as expected. However, when I try to use a custom segue class, the navigation bar disappears. After checking, the navigation controller is absent from the post-custom segue view controller. So it seems the problem comes from using a custom segue: how can I stay within the navigation controller with a custom segue? Here is my custom segue code, which purpose is to make the segue have a slide effect from top to bottom:
class FirstCustomSegue: UIStoryboardSegue {
override func perform() {
var firstVCView = self.sourceViewController.view as UIView!
var secondVCView = self.destinationViewController.view as UIView!
// Get the screen width and height.
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
// Specify the initial position of the destination view.
secondVCView.frame = CGRectMake(0.0, -screenHeight, screenWidth, screenHeight)
// Access the app's key window and insert the destination view above the current (source) one.
let window = UIApplication.sharedApplication().keyWindow
window?.insertSubview(secondVCView, aboveSubview: firstVCView)
// Animate the transition.
UIView.animateWithDuration(1, animations: { () -> Void in
firstVCView.frame = CGRectOffset(firstVCView.frame, 0.0, screenHeight)
secondVCView.frame = CGRectOffset(secondVCView.frame, 0.0, screenHeight)
}) { (Finished) -> Void in
self.sourceViewController.presentViewController(self.destinationViewController as! UIViewController,
animated: false,
completion: nil)
}
}
}
Upvotes: 1
Views: 417
Reputation: 6806
I think that for a custom segue, you have to execute a navigationController.pushViewController()
operation to make the new VC appear on the old NC stack. I can't see a way to make that happen with a custom segue. However, I do see a way to make it look like it happens:
class FirstCustomSegue: UIStoryboardSegue {
override func perform() {
let firstVCView = self.sourceViewController.view as UIView!
let secondVCView = self.destinationViewController.view as UIView!
// Get the screen width and height.
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
// Specify the initial position of the destination view.
secondVCView.frame = CGRectMake(0.0, -screenHeight, screenWidth, screenHeight)
// make a UIView which looks like the sourceViewController's view,
// and add it to the destinationViewcontrollers's view,
// in the right place so it looks as though it does not move
let v1 = firstVCView.snapshotViewAfterScreenUpdates(false)
v1.frame = CGRectMake(0, screenHeight, screenWidth, screenHeight)
secondVCView.addSubview(v1)
// push the destination VC without animation
// but it looks the same as the first so it seems as though nothing has happened.
self.sourceViewController.navigationController?.pushViewController(self.destinationViewController, animated: false)
// Animate the transition.
UIView.animateWithDuration(1, animations: { () -> Void in
secondVCView.frame = CGRectOffset(secondVCView.frame, 0.0, screenHeight)
}) { (Finished) -> Void in
v1.removeFromSuperview()
}
}
}
That does the pushViewController
without an animation, then makes it look like it is animated by putting a snapshot of the source view temporarily onto the second view. It looks OK on my iPad.
Upvotes: 1