update react objective kit objective-c xcode facebook ios6 appdelegate

objective c - react - AppDelegate, rootViewController y presentViewController



react native facebook sdk (5)

Estoy haciendo el tutorial de integración de Facebook, quiero mostrar mi MainViewViewController si el usuario tiene un token válido para el estado actual; de lo contrario, quiero mostrar LoginViewController.

MainViewAppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) { // To-do, show logged in view } else { // No, display the login page. [self showLoginView]; } return YES; } - (void)showLoginView { UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; LoginViewController* loginViewController = [mainstoryboard instantiateViewControllerWithIdentifier:@"LoginViewController"]; [self.window.rootViewController presentViewController:loginViewController animated:YES completion:NULL]; }

Error de consola:

Warning: Attempt to present <LoginViewController: 0xb492fd0> on <MainViewViewController: 0xb1bd820> whose view is not in the window hierarchy!

No quiero usar un NavigationController.


En Swift 3: -

let storyboard = UIStoryboard(name: "Login", bundle: nil) let viewController = storyboard.instantiateViewController(withIdentifier: "LoginViewController") window?.makeKeyAndVisible() window?.rootViewController?.present(viewController, animated: true, completion: nil)


En el caso, cuando no estás usando un guión gráfico. Primero necesitas crear YourViewController. Ir a Archivo -> Nuevo -> Archivo ... (o shortCut - comando + N)

Después de eso, elige Cocoa Touch Class. Haga clic en Siguiente o Ingrese

Que escriba el nombre de su viewController y haga clic en Siguiente

#import "AppDelegate.h" #import "YourViewController.h" @interface AppDelegate () @end @implementaion AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Init window self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; [self.window makeKeyAndVisible]; // Init YourViewController YourViewController *viewController = [[YourViewController alloc] init]; // Init YourNavigationController UINavigationController *navigationContoller = [[UINavigationController alloc] initWithRootViewController: viewController]; // Set rootViewController self.window.rootViewController = navigationContoller; return YES; } @end

Swift 3/4 Ejemplo

import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { //1-st step window = UIWindow(frame: UIScreen.main.bounds) window?.makeKeyAndVisible() //2-nd - create a window root controller, and create a layout let layout = UICollectionViewFlowLayout() window?.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout)) return true

}


En ocasiones, la presentación del controlador de vista modal desde window.rootViewController puede producir la misma advertencia y no tiene ningún efecto. Ejemplo de dicha jerarquía de controladores de vista:

  1. [ MYUITableViewController ] (presentado de forma modal por MYUIViewController)
  2. [ MYUIViewController ] (rootViewController de UINavigationController a continuación)
  3. [ UINavigationController ] (root)

Ahora llamando

[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:[UIViewController new] animated:YES completion:nil];

causará esta advertencia exacta (probado en iOS6 y 7 Sim)

Solución: en lugar de usar rootViewController, use el superior presentado por él:

UIViewController *topRootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; while (topRootViewController.presentedViewController) { topRootViewController = topRootViewController.presentedViewController; } [topRootViewController presentViewController:yourController animated:YES completion:nil];

  • A veces, KeyWindow puede haber sido reemplazado por una ventana con nil rootViewController (que muestra UIAlertViews, UIActionSheets en iPhone, etc.), en ese caso debe usar la propiedad de ventana de UIView.

Tuve el mismo problema. En función de la respuesta a esta pregunta , agregué [self.window makeKeyAndVisible] justo antes de presentViewController:animated:completion: y eso lo arregló para mí.

En su caso, showLoginView se convierte

- (void)showLoginView { UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; LoginViewController *loginViewController = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"]; [self.window makeKeyAndVisible]; [self.window.rootViewController presentViewController:loginViewController animated:YES completion:NULL]; }


¡La respuesta de Stepan Generalov fue la correcta para mí en Swift 3 !
Por supuesto, con la nueva sintaxis, etc., así que la copiaré aquí:

let sb = UIStoryboard(name: "Main", bundle: nil) let vc = sb.instantiateViewController(withIdentifier: "MainApp") as! ViewController var topRootViewController: UIViewController = (UIApplication.shared.keyWindow?.rootViewController)! while((topRootViewController.presentedViewController) != nil){ topRootViewController = topRootViewController.presentedViewController! } topRootViewController.present(vc, animated: true, completion: nil)

"MainApp" es el identificador de mi controlador de vista principal en este caso.

Sé que hay otras formas, pero si necesita tener diferentes esquemas de URL para abrir diferentes partes de su aplicación, debe manejarlo en AppDelegate, así que esto es perfecto porque en el

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {}

método, puede simplemente verificar qué url es como una Cadena y luego decidir si ejecuta el código escrito anteriormente o tal vez uno similar con un identificador diferente para otro controlador de vista ( withIdentifier )