Last active
December 1, 2015 13:19
-
-
Save warren-gavin/c4f2c593db1360db1ab1 to your computer and use it in GitHub Desktop.
Custom segue class that launches a new storyboard.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// APLaunchNewStoryboardSegue.swift | |
// APLaunchNewStoryboardSegue gist | |
// | |
// Created by Warren Gavin on 30/11/15. | |
// Copyright © 2015 Apokrupto. All rights reserved. | |
// | |
import UIKit | |
/** | |
* Custom segue class that launches a new storyboard. This will appear in the storyboard's segue list | |
* when creating a new segue as "launch new storyboard" | |
* | |
* To use the segue in a storyboad: | |
* o Select it as the custom segue when linking two view controllers | |
* o The destination view controller should be a simple blank VC, it is a place holder. | |
* o Name the segue identifier <storyboard>[.<scene>] | |
* - i.e If you want to launch the storyboard "Foo.storyboard" name the | |
* segue "Foo". If you want to launch a specific scene "bar" in the | |
* storyboard "Foo.storyboard" name the segue "Foo.bar" | |
* o All storyboards MUST have an initial view controller, if they don't | |
* the placeholder destination view controller will be presented | |
* | |
*/ | |
@objc(APLaunchNewStoryboardSegue) // See http://stackoverflow.com/questions/24185345/custom-segue-in-swift why this is necessary | |
class APLaunchNewStoryboardSegue: UIStoryboardSegue { | |
override init(identifier: String?, source: UIViewController, destination: UIViewController) { | |
var realDestination = APLaunchNewStoryboardSegue.controllerForNewSceneInStoryboard(identifier) | |
if nil == realDestination { | |
realDestination = destination | |
} | |
super.init(identifier: identifier, source: source, destination: realDestination!) | |
} | |
override func perform() { | |
let source = self.sourceViewController | |
if source.respondsToSelector("showViewController:sender:") { | |
source.showViewController(self.destinationViewController, sender: source) | |
} | |
else if let naviationController = source.navigationController { | |
naviationController.pushViewController(self.destinationViewController, animated: true) | |
} | |
else { | |
source.presentViewController(self.destinationViewController, animated: true, completion: nil) | |
} | |
} | |
} | |
private extension APLaunchNewStoryboardSegue { | |
/** | |
* Create a view controller for a particular scene in a particular storyboard | |
* | |
* @param sceneNameWithStoryboard Defined as "storyboard_name" or "storyboard_name.scene_name" | |
* for a specific scene in the storyboard. | |
* If no scene name is given the initial view controller for | |
* the storyboard is returned. | |
* | |
* @return view controller for a storyboard scene | |
*/ | |
private static func controllerForNewSceneInStoryboard(sceneNameWithStoryBoard: String?) -> UIViewController? { | |
guard let sceneNameWithStoryBoard = sceneNameWithStoryBoard where sceneNameWithStoryBoard.characters.count > 0 else { | |
return nil | |
} | |
// Segue components are [storyboard, sceneName] or [storyboard] | |
let segueComponents = sceneNameWithStoryBoard.componentsSeparatedByString(".") | |
let storyboard = UIStoryboard(name: segueComponents[0], bundle: nil) | |
// If no scene specified, return the initial view controller | |
if 1 == segueComponents.count { | |
return storyboard.instantiateInitialViewController() | |
} | |
return storyboard.instantiateViewControllerWithIdentifier(segueComponents[1]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment