2011-12-21 10 views
10

En ShareKit, el código necesita determinar dónde está el control raízViewController para que pueda mostrar una vista modal. Por alguna razón, el código no está cumpliendo con iOS 5:Encontrar rootViewController en iOS

// Try to find the root view controller programmically 

    // Find the top window (that is not an alert view or other window) 
    UIWindow *topWindow = [[UIApplication sharedApplication] keyWindow]; 
    if (topWindow.windowLevel != UIWindowLevelNormal) 
    { 
     NSArray *windows = [[UIApplication sharedApplication] windows]; 
     for(topWindow in windows) 
     { 
      if (topWindow.windowLevel == UIWindowLevelNormal) 
       break; 
     } 
    } 

    UIView *rootView = [[topWindow subviews] objectAtIndex:0]; 
    id nextResponder = [rootView nextResponder]; 

    if ([nextResponder isKindOfClass:[UIViewController class]]) 
     self.rootViewController = nextResponder; 

    else 
     NSAssert(NO, @"ShareKit: Could not find a root view controller. You can assign one manually by calling [[SHK currentHelper] setRootViewController:YOURROOTVIEWCONTROLLER]."); 

Esto está afectando a la aserción.

¿Qué hay de malo simplemente con usar el siguiente código?

rootViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController]; 

Parece que funciona bien. ¿Fallará bajo algunas condiciones?

Respuesta

27

No estoy seguro de si puede confiar en window.rootViewController b/c, no es necesario configurarlo. Solo puede agregar una subvista a la ventana. El siguiente parecía funcionar bien:

id rootVC = [[[[[UIApplication sharedApplication] keyWindow] subviews] objectAtIndex:0] nextResponder]; 
+0

Gracias. El controlador rootViewController está configurado, en este caso. No está claro para mí que el hecho de configurarlo automáticamente lo convierta en el control raíz de control para este código de ShareKit. Esta es una aplicación universal, y en el código de iPhone, el RootViewController es un UITabBarController subclasificado. Debo agregar que también tengo un UIAlertView y UIView agregados como subvistas a la ventana de la aplicación. (Puedo mostrar uno o ambos, independientemente de la vista que muestre tabbarcontroller). Su código devuelve UIAlertView como objectAtIndex: 0. Podría repetir el resto, supongo. – Jim

+1

si lo configura en su aplicación, entonces definitivamente funcionará. No sabía si creabas una biblioteca para que otros la usen y no puedes confiar en que se configure 'window.rootViewController'. – XJones

+0

@XJones, ¿qué ocurre si window.rootViewController no está configurado? ¿Hay alguna otra forma de obtener de forma confiable el controlador de vista actual? – Zennichimaro

1

forma rápida de hacerlo, puede llamar a esto desde cualquier lugar:

/// EZSwiftExtensions - Gives you the VC on top so you can easily push your popups 
public var topMostVC: UIViewController? { 
    var presentedVC = UIApplication.sharedApplication().keyWindow?.rootViewController 
    while let pVC = presentedVC?.presentedViewController { 
     presentedVC = pVC 
    } 

    if presentedVC == nil { 
     print("EZSwiftExtensions Error: You don't have any views set. You may be calling them in viewDidLoad. Try viewDidAppear instead.") 
    } 
    return presentedVC 
} 

Su incluido como una función estándar en:

https://github.com/goktugyil/EZSwiftExtensions

Cuestiones relacionadas