ios - online - swift playground run
Instalar y presentar un controlador de vista en Swift (13)
¡La respuesta de akashivsky funciona bien! Pero, en caso de que tenga problemas para volver del controlador de vista presentado, esta alternativa puede ser útil. ¡Funcionó para mí!
Rápido:
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController
// Alternative way to present the new view controller
self.navigationController?.showViewController(vc, sender: nil)
Obj-C:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"someViewController"];
[self.navigationController showViewController:vc sender:nil];
Problema
Comencé a echar un vistazo al nuevo Swift
en Xcode 6
y probé algunos proyectos de demostración y tutoriales. Ahora estoy atascado en:
viewController
una instancia y luego presentar un viewController
desde un guión gráfico específico
Solución Objective-C
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"myStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"myVCID"];
[self presentViewController:vc animated:YES completion:nil];
¿Cómo lograr esto en Swift?
Creé una biblioteca que manejará esto mucho más fácil con una mejor sintaxis:
https://github.com/Jasperav/Storyboardable
Simplemente cambie Storyboard.swift y deje que los ViewControllers
ajusten a Storyboardable
.
Me gustaría sugerir una forma mucho más limpia. Esto será útil cuando tengamos múltiples guiones gráficos.
1.Crear una estructura con todos tus guiones gráficos.
struct Storyboard {
static let main = "Main"
static let journey = "login"
static let journey = "profile"
static let journey = "home"
}
2. Crea una extensión de UIStoryboard como esta
extension UIStoryboard {
@nonobjc class var main: UIStoryboard {
return UIStoryboard(name: Storyboard.main, bundle: nil)
}
@nonobjc class var journey: UIStoryboard {
return UIStoryboard(name: Storyboard.login, bundle: nil)
}
@nonobjc class var quiz: UIStoryboard {
return UIStoryboard(name: Storyboard.profile, bundle: nil)
}
@nonobjc class var home: UIStoryboard {
return UIStoryboard(name: Storyboard.home, bundle: nil)
}
}
Dé el identificador del guión gráfico como el nombre de la clase y use el siguiente código para crear una instancia
let loginVc = UIStoryboard.login.instantiateViewController(withIdentifier: "/(LoginViewController.self)") as! LoginViewController
No importa lo que haya intentado, simplemente no funcionaría para mí, no hay errores, pero tampoco hay un nuevo controlador de vista en mi pantalla. No sé por qué, pero envolverlo en la función de tiempo de espera finalmente lo hizo funcionar:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.0) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "TabletViewController")
self.present(controller, animated: true, completion: nil)
}
Para las personas que usan la respuesta de @ akashivskyy para crear UIViewController
instancia de UIViewController
y tienen la excepción:
error fatal: uso del inicializador no implementado ''init (codificador :)'' para la clase
Consejo rapido:
¿Implementar manualmente el required init?(coder aDecoder: NSCoder)
en su UIViewController
destino que está intentando crear una instancia
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
Si necesita más descripción, por favor consulte mi respuesta here
Sé que es un subproceso antiguo, pero creo que la solución actual (usando el identificador de cadena codificado para el controlador de vista dado) es muy propensa a errores.
He creado un script de tiempo de compilación (al que puede acceder aquí ), que creará una forma segura para que el compilador acceda y cree instancias de controladores de vista desde todo el guión gráfico dentro del proyecto dado.
Por ejemplo, el controlador de vista llamado vc1 en Main.storyboard se instanciará así:
let vc: UIViewController = R.storyboard.Main.vc1^ // where the ''^'' character initialize the controller
Si quieres presentarlo modalmente, deberías tener algo como a continuación:
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewControllerID")
self.showDetailViewController(vc as! YourViewControllerClassName, sender: self)
Si tiene un controlador de visualización que no utiliza ningún guión gráfico / Xib, puede ingresar a este VC en particular, como en la siguiente llamada:
let vcInstance : UIViewController = yourViewController()
self.present(vcInstance, animated: true, completion: nil)
Swift 3
let settingStoryboard : UIStoryboard = UIStoryboard(name: "SettingViewController", bundle: nil)
let settingVC = settingStoryboard.instantiateViewController(withIdentifier: "SettingViewController") as! SettingViewController
self.present(settingVC, animated: true, completion: {
})
Swift 4:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC
Todo es cuestión de la nueva sintaxis, la funcionalidad no ha cambiado:
// Swift 3.0
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "someViewController")
self.present(controller, animated: true, completion: nil)
Si tiene problemas con init(coder:)
, consulte la respuesta de EridB .
Este enlace tiene ambas implementaciones:
Rápido:
let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
self.presentViewController(viewController, animated: false, completion: nil)
C objetivo
UIViewController *viewController = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:@"ViewController"];
Este enlace tiene código para iniciar viewcontroller en el mismo guión gráfico.
/*
Helper to Switch the View based on StoryBoard
@param StoryBoard ID as String
*/
func switchToViewController(identifier: String) {
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier(identifier) as! UIViewController
self.navigationController?.setViewControllers([viewController], animated: false)
}
// "Main" is name of .storybord file "
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
// "MiniGameView" is the ID given to the ViewController in the interfacebuilder
// MiniGameViewController is the CLASS name of the ViewController.swift file acosiated to the ViewController
var setViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MiniGameView") as MiniGameViewController
var rootViewController = self.window!.rootViewController
rootViewController?.presentViewController(setViewController, animated: false, completion: nil)
Esto funcionó bien para mí cuando lo puse en AppDelegate