Custom segue a un storyboard diferente

Pregunta:

¿Cómo podría uno escribir un segue personalizado que le permitiera incrustar controlleres de vista de un guión gráfico diferente?

Context:

Estoy intentando escribir un segue personalizado con el que puedo vincular de un storyboard a otro. Un buen artículo sobre atomicobject.com ilustra cómo crear una segue que se origina a partir de un button / evento, etc. Traducido al swift, y que permite a los UINavigationControllers no, el código se ve así:

public class SegueToStoryboard : UIStoryboardSegue { private class func viewControllerInStoryBoard(identifier:String, bundle:NSBundle? = nil) -> UIViewController? { let boardScene = split(identifier, { $0 == "." }, maxSplit: Int.max, allowEmptySlices: false) switch boardScene.count { case 2: let sb = UIStoryboard(name: boardScene[0], bundle: bundle) return sb.instantiateViewControllerWithIdentifier(boardScene[1]) as? UIViewController case 1: let sb = UIStoryboard(name: boardScene[0], bundle: bundle) return sb.instantiateInitialViewController() as? UIViewController default: return nil } } override init(identifier: String!, source: UIViewController, destination ignore: UIViewController) { let target = SegueToStoryboard.viewControllerInStoryBoard(identifier, bundle: nil) super.init(identifier: identifier, source: source, destination:target != nil ? target! : ignore) } public override func perform() { let source = self.sourceViewController as UIViewController let dest = self.destinationViewController as UIViewController source.addChildViewController(dest) dest.didMoveToParentViewController(source) source.view.addSubview(dest.view) // source.navigationController?.pushViewController(dest, animated: true) } } 

Problema:

El problema que estoy teniendo tanto con su Obj-C como con el código Swift anterior es que cuando intenta utilizar la vista de contenedor (con semántica de una segregación de inserción, comenzando con una segregación de inserción, eliminando la segue y luego se usa el segue personalizado anterior), se bloquea antes de llamar al código segue con el siguiente error method-not-found:

*** Finalización de la aplicación debido a la exception no detectada 'NSUnknownKeyException', motivo: '[<UIStoryboardSegueTemplate 0x7ffc8432a4f0> setValue: forUndefinedKey:]: esta class no cumple con la encoding de valor key para la key containerView.'

He intentado inspeccionar la dirección indicada pero no obtuve resultados significativos. Hago ver la statement en negrita de que espera el contenedorView pero no sé cómo aislar, satisfacer o solucionar este problema.

Resumen:

Mi objective final es incrustar controlleres de vista definidos en guiones charts separados para facilitar la queueboración y las testings sin tener que escribir código adicional (una solución no invasiva). ¿Alguien tiene alguna idea de cómo llevar a cabo esta tarea mayor? Podría recurrir al enfoque híbrido de llamar a performSegue, pero me gustaría encontrar una solución única, completa y completa. El código anterior llega para events seguidos (botones, etc.), pero no con la segregación de inserción.

Cualquier input es apreciada, gracias de antemano.

Su enfoque funciona bien para segues personalizados para mostrar / desplegar de forma modal otros controlleres de vista, pero no para insert segues. La razón de esto es que la segue "Incrustar" no es una subclass de UIStoryboardSegue sino que henetworkinga de UIStoryboardSegueTemplate, que es una API privada.

Desafortunadamente, no pude encontrar una manera mejor de lograr lo que quieres que con el enfoque híbrido.

Mi manera es vincular el contenedorView y eliminar el viewDidLoad segue de él. y llamar manualmente a segue en viewdidLoad

 public protocol EmbeddingContainerView { var containerView: UIView! { get set } } public class CoreSegue: UIStoryboardSegue { public static func instantiateViewControllerWithIdentifier(identifier: String) -> UIViewController { let storyboard = UIStoryboard(name: "Core", bundle: NSBundle(forClass: self)) let controller = storyboard.instantiateViewControllerWithIdentifier(identifier) as! UIViewController return controller } var isPresent = false var isEmbed = false override init!(identifier: String?, source: UIViewController, destination: UIViewController) { if var identifier = identifier { if identifier.hasPrefix("present ") { isPresent = true identifier = identifier.substringFromIndex(advance(identifier.startIndex, count("present "))) } if identifier.hasPrefix("embed ") { isEmbed = true identifier = identifier.substringFromIndex(advance(identifier.startIndex, count("embed "))) } let controller = CoreSegue.instantiateViewControllerWithIdentifier(identifier) super.init(identifier: identifier, source: source, destination: controller) } else { super.init(identifier: identifier, source: source, destination: destination) } } public override func perform() { if let source = sourceViewController as? UIViewController, dest = destinationViewController as? UIViewController { if isPresent { let nav = UINavigationController(rootViewController: dest) nav.navigationBarHidden = true // you might not need this line source.presentViewController(nav, animated: true, completion: nil) } else if isEmbed { if let contentView = (source as? EmbeddingContainerView)?.containerView { source.addChildViewController(dest) contentView.addSubview(dest.view) dest.view.fullDimension() // which comes from one of my lib } } else { source.navigationController?.pushViewController(destinationViewController as! UIViewController, animated: true) } } } } 

y más tarde en su código:

 class MeViewController: UIViewController, EmbeddingContainerView { @IBOutlet weak var containerView: UIView! override func viewDidLoad() { super.viewDidLoad() performSegueWithIdentifier("embed Bookings", sender: nil) } }