ios - present - Crear una instancia de View Controller desde Storyboard vs. Crear nueva instancia
swift present view controller programmatically (7)
En Swift puedes hacer lo mismo con,
var someVC = self.storyboard?.instantiateViewControllerWithIdentifier("SomeViewController") as! SomeViewController
Tendrá que dar el identificador en el guión gráfico al control SomeViewController y marcar la marca de verificación para usar la identificación del guion gráfico.
¿Cuál es la diferencia funcional entre instanciar un Controlador de Vista del guión gráfico y crear una nueva instancia del mismo? Por ejemplo:
#import "SomeViewController.h"
...
SomeViewController *someViewController = [SomeViewController new];
versus
#import "SomeViewController.h"
...
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
SomeViewController *someViewController = [storyboard instantiateViewControllerWithIdentifier:@"SomeViewController"];
En cualquier caso, ¿ someViewController
es efectivamente lo mismo?
En caso de que no desee crear una instancia de un nuevo VC utilizando instantiateViewControllerWithIdentifier
pero accediendo a la instancia creada por el guión gráfico desde AppDelegate:
- crear una propiedad en AppDelegate.h para que sea accesible desde las clases que lo usan
@property (nonatomic, strong) myViewControllerClass*vC;
- en
viewDidLoad
dentro de myViewControllerClass.m Accedo a la instancia compartida de AppDelegate y cargo la propiedad con self:[AppDelegate sharedInstance].vC = self;
Tuve que usar esta solución en un guión gráfico complejo y todavía no puedo olvidar el hecho de que no puedo encontrar una manera fácil de acceder a todos (o al menos los que necesito) los objetos en el guión gráfico simplemente dirigiéndome a sus identificadores.
En el segundo caso, el controlador de vista cargará su vista desde el guión gráfico y usted estará contento.
En el primer caso, no lo hará. A menos que hayas tomado otras medidas (como anular loadView
o viewDidLoad
o crear un xib llamado SomeViewController.xib
), obtendrás una vista blanca vacía y estarás triste.
La principal diferencia radica en la forma de UIViewController
instancias de las subvistas de su UIViewController
.
En el segundo caso, todas las vistas que cree en su guión gráfico se crearán automáticamente para usted, y todos los puntos de venta y las acciones se configurarán según lo especificado en el guión gráfico.
En el primer caso, nada de eso sucede; simplemente obtienes el objeto sin procesar. Necesitará asignar e instanciar todas sus subvistas, establecerlas usando restricciones u otras, y conectar todas las salidas y acciones usted mismo. Apple recomienda hacer esto anulando el método UIViewController
de UIViewController
.
No es la misma cosa. En el guión gráfico probablemente tengas algunos elementos de UI. Pueden tener restricciones y propiedades configuradas a través del guión gráfico. Cuando crea una instancia del viewcontroller a través del guión gráfico, obtiene todas las instrucciones para saber dónde están esas subvistas y cuáles son sus propiedades. Si solo dice [SomeViewController new]
, no obtendrá todas las instrucciones que el guión gráfico tiene para el controlador de vista.
Una buena prueba será agregar un UIViewController a un guión gráfico y arrastrar una vista roja sobre él. Crear una instancia con ambos métodos y ver cuáles son las diferencias.
Otra cosa para comprobar es si el controlador de vista que está arrojando el error tiene un storyboardIdentifier, puede verificar el archivo xib del guión gráfico.
el identificador faltaba en mi caso, el error se detuvo cuando lo agregué
simple swift 3 extension
fileprivate enum Storyboard : String {
case main = "Main"
}
fileprivate extension UIStoryboard {
static func loadFromMain(_ identifier: String) -> UIViewController {
return load(from: .main, identifier: identifier)
}
static func load(from storyboard: Storyboard, identifier: String) -> UIViewController {
let uiStoryboard = UIStoryboard(name: storyboard.rawValue, bundle: nil)
return uiStoryboard.instantiateViewController(withIdentifier: identifier)
}
}
// MARK: App View Controllers
extension UIStoryboard {
class func loadHomeViewController() -> HomeViewController {
return loadFromMain("HomeViewController") as! HomeViewController
}
}