2011-12-21 76 views
10

在ShareKit中,代碼需要確定rootViewController的位置,以便它可以顯示模態視圖。由於某些原因,代碼在iOS 5中失敗:在iOS中查找rootViewController

// 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]."); 

這是觸發斷言。

簡單地使用下面的代碼有什麼問題呢?

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

這似乎工作正常。在某些情況下會失敗嗎?

回答

27

我不確定您是否可以依靠window.rootViewController b/c您不必設置它。你可以在窗口中添加一個子視圖。下面似乎很好地工作:

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

謝謝。在這種情況下,rootViewController被設置。我不清楚,只是設置自動使它成爲這個ShareKit代碼的rootViewController。這是一個通用的應用程序,在iPhone代碼中,rootViewController是一個子類UITabBarController。我應該補充說我還有一個UIAlertView和UIView作爲子視圖添加到應用程序窗口中。 (無論tabbarcontroller顯示哪個視圖,我都可以顯示其中的一個或兩個)。您的代碼返回UIAlertView作爲objectAtIndex:0。我想我可以重複其餘的。 – Jim 2011-12-21 07:28:33

+1

如果你在你的應用程序中設置它,那麼它肯定會工作。我不知道你是否爲別人創建了一個庫,以便你不能依賴設置的'window.rootViewController'。 – XJones 2011-12-21 07:30:25

+0

@XJones,如果window.rootViewController未設置,該怎麼辦?有沒有其他方法可靠地獲取當前的視圖控制器? – Zennichimaro 2013-03-06 06:59:37

1

斯威夫特辦法做到這一點,你可以從任何地方調用這個:

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

其包括在標準功能:

https://github.com/goktugyil/EZSwiftExtensions