ios - from - load xib swift 4
Restablecer el guión gráfico al cerrar sesión (3)
Lo siguiente funciona muy bien para mí, si usa una estructura basada en NavController:
UIWindow *window = [[UIApplication sharedApplication].windows firstObject];
UINavigationController *navController = (UINavigationController *)window.rootViewController;
UIViewController *vc = [navController.storyboard instantiateViewControllerWithIdentifier:@"Login"];
navController.viewControllers = @[vc];
Para que esto funcione, debe asignar el "Inicio de sesión" del Storyboard ID a su Login VC.
Estoy creando una aplicación de cliente web IOS 5.1 que utiliza un guión gráfico. Una de mis acciones es "cerrar sesión", durante la cual quiero restablecer mi vista de raíz a la vista inicial creada por la vista de raíz del Storyboard. (Al iniciar sesión, algunos elementos de la vista se eliminan o se agregan según quién eres; cuando cierras la sesión, quiero restablecerlos a sus valores predeterminados, que he especificado en el guión gráfico).
Me doy cuenta de que puedo restablecer / agregar todos los elementos mediante programación, pero ¿de qué sirve el guión gráfico? Me imagino que tiene que haber una manera de volver al punto de partida recargando el archivo de vista, ¿verdad?
Lo siguiente funciona para mí, si uso una estructura basada en UISplitViewController
(probada en iOS 8+):
Elimine el Guión gráfico de Proyectos General -> Información de implementación , por lo que el menú desplegable es similar al siguiente y debe configurar el guión gráfico en código.
En algún lugar en AppDelegate.m
- (void)setupViewControllers
{
// check for thread, as this method might be called by other (e.g. logout) logic
if ([NSThread currentThread] != [NSThread mainThread]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self setupViewControllers];
});
return;
}
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
UIViewController *vc =[storyboard instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = vc;
// configure split vc
// Note: I reference split vc for my own purpose, but it is your mater of choice
self.splitViewController = (UISplitViewController *)self.window.rootViewController;
self.splitViewController.delegate = self;
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
self.splitViewController.preferredPrimaryColumnWidthFraction = 0.5;
[self.window makeKeyAndVisible];
}
Para evitar duplicados de código, llame a esta función desde la application:didFinishLaunchingWithOptions:
como configuración por primera vez
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// some code...
[self setupViewControllers];
// Optional: add splash view (e.g. [self addSplashView];)
// some code...
}
Dentro de un controlador de vista que está listo para presentar la IU al usuario, elimine la vista de bienvenida. Por ejemplo (en Swift):
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if !AppSession.currentSession().isLoggedIn() {
presentLoginViewController(false, completion: { ()->Void in
self.removeSplash()
})
}
else {
removeSplash()
}
// some code...
}
private func removeSplash() {
if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
appDelegate.removeSplashView()
}
}
Encontré que el siguiente enfoque funciona para mí. Tenga en cuenta que uso ARC, no estoy seguro si esto tiene mucho que ver con la solución. Primero, en la clase del delegado de la aplicación, en la application:didFinishLaunchingWithOptions:
la instancia inicial del Storyboard con la siguiente línea de código:
_initalStoryboard = self.window.rootViewController.storyboard;
(Obviamente hay una variable de instancia UIStoryboard* _initalStoryboard;
)
Luego tengo la siguiente función definida en mi delegado de aplicación:
- (void)resetWindowToInitialView
{
for (UIView* view in self.window.subviews)
{
[view removeFromSuperview];
}
UIViewController* initialScene = [_initalStoryboard instantiateInitialViewController];
self.window.rootViewController = initialScene;
}
Tenga en cuenta el bucle for in que elimina todas las subvistas de la window
. La documentación de UIWindow rootViewController establece:
Si la ventana tiene una jerarquía de vistas existente, las vistas anteriores se eliminan antes de que se instalen las nuevas.
Sin embargo, no encontré que este fuera el caso ... así que elimino las vistas existentes yo mismo explícitamente antes de asignar un nuevo controlador rootViewController. No he encontrado ningún efecto secundario preocupante o pérdida de memoria utilizando este método. No soy de ninguna manera un experto en la magia de UIKit, por lo que le sugeriría que haga una prueba y vuelva a probar esta solución si planea usarla usted mismo. Aclamaciones