2011-12-21 10 views
10

In ShareKit, il codice deve determinare dove è il rootViewController in modo che possa mostrare una vista modale. Per qualche motivo, il codice non funziona in iOS 5:Ricerca del rootViewController in 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]."); 

Questo sta colpendo l'assert.

Cosa c'è di sbagliato semplicemente usando il seguente codice, invece?

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

Questo sembra funzionare bene. Fallirà in alcune condizioni?

risposta

27

Non so se si può fare affidamento su window.rootViewController b/c non è necessario impostarlo. Puoi semplicemente aggiungere una sottoview alla finestra. Quanto segue è sembrato funzionare bene:

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

Grazie. In questo caso, viene impostato rootViewController. Non mi è chiaro che solo l'impostazione che rende automaticamente il rootViewController ai fini di questo codice ShareKit. Questa è un'app universale e nel codice dell'iPhone, rootViewController è un UITabBarController sottoclassato. Devo aggiungere che ho anche UIAlertView e UIView aggiunti come subviews alla finestra dell'applicazione. (Posso mostrarne uno o entrambi, indipendentemente dalla vista mostrata dal tabbarcontroller.) Il tuo codice restituisce UIAlertView come objectAtIndex: 0. Potrei solo ripetere il resto, credo. – Jim

+1

se lo stai impostando nella tua app, funzionerà sicuramente. Non sapevo se stavi creando una libreria che altri possano usare dove non puoi fare affidamento sul fatto che 'windows.rootViewController' sia impostato. – XJones

+0

@XJones, cosa succede se window.rootViewController non è impostato? c'è un altro modo per ottenere in modo affidabile il controller di visualizzazione corrente? – Zennichimaro

1

modo Swift per farlo, è possibile chiamare questo da qualsiasi luogo:

/// 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 
} 

La sua incluso come funzione standard:

https://github.com/goktugyil/EZSwiftExtensions

Problemi correlati