Skip to content

Instantly share code, notes, and snippets.

@warren-gavin
Last active December 1, 2015 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save warren-gavin/c4f2c593db1360db1ab1 to your computer and use it in GitHub Desktop.
Save warren-gavin/c4f2c593db1360db1ab1 to your computer and use it in GitHub Desktop.
Custom segue class that launches a new storyboard.
//
// 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