Czy istnieje sposób na pobranie bieżącego kontrolera widoku z AppDelegate? Wiem, że jest rootViewController, ale to nie jest to, czego szukam.Aktualny kontroler widoku z AppDelegate?
Odpowiedz
Jeśli masz UINavigationController w appDelegate następnie użyć jej właściwość topViewController lub visibleViewController
Uzyskaj obiekt appDelegate:
MyAppDelegate *tmpDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Jak berylu zaproponował można użyć właściwości UINavigationController, aby uzyskać dostęp do bieżącego kontrolera widoku.
Więc kod wyglądałby następująco:
id myCurrentController = tmpDelegate.myNavigationController.topViewController;
lub:
NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;
Jeśli widok główny kontroler Twojej aplikacji jest UINavigationController
można to zrobić:
((UINavigationController*)appDelegate.window.rootViewController).visibleViewController;
Podobnie, jeśli jest to UITabBarController
, możesz to zrobić:
((UITabBarController*)appDelegate.window.rootViewController).selectedViewController;
Oczywiście jawne rzucanie w ten sposób jest brudne. Lepiej byłoby uchwycić referencję przy użyciu silnych typów.
Dla każdego nie używając UINavigationController
ale raczej ich widok domyślny kontroler jest UIViewController
można sprawdzić, które zobaczyć kontroler jest aktywny (lub przedstawiony) z następujących w AppDelegate
:
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
if let rootViewController = self.window!.rootViewController {
if let presentedViewController = rootViewController.presentedViewController {
return presentedViewController.supportedInterfaceOrientations()
}
} // Else current view controller is DefaultViewController
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
Jak widać Sprawdzam bieżący kontroler widoku, aby obsługiwać różne orientacje interfejsu dla określonych kontrolerów widoku. W przypadku każdego kontrolera widoku, który wymaga określonej orientacji, należy umieścić każdą osobę zainteresowaną użyciem tej metody w celu wspierania konkretnych.
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.All.rawValue)
}
Uwaga: Kod ten został napisany z Swift 1.2
Nawet lepiej, zmień 'if let' na' while let' tak, aby uzyskać najwyższą wartość. – milesper
To może pomóc
- (UIViewController *)topViewController{
return [self topViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}
- (UIViewController *)topViewController:(UIViewController *)rootViewController
{
if (rootViewController.presentedViewController == nil) {
return rootViewController;
}
if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
return [self topViewController:lastViewController];
}
UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
return [self topViewController:presentedViewController];
}
wersję SWIFT:
extension UIApplication {
class func topViewController(base: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return topViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(base: presented)
}
return base
}
}
muszę kochać rekursję, dzięki :) –
można uzyskać bieżący kontroler widok od rootViewController szukając jej presentedViewController, tak:
UIViewController *parentViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;
while (parentViewController.presentedViewController != nil){
parentViewController = parentViewController.presentedViewController;
}
UIViewController *currentViewController = parentViewController;
Pracuje ze mną.Nadzieję, że to pomaga :)
Uratowałem mój dzień. Dziękujemy +1 – crash
najlepsza, Dzięki –
Swift Rozwiązanie:
self.window.rootViewController.presentedViewController.
To powinno Ci to, czego potrzebujesz.
Złóż rozszerzenia:
extension UIApplication {
class func topViewController(base: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(nav.visibleViewController)
}
if let tab = base as? UITabBarController {
let moreNavigationController = tab.moreNavigationController
if let top = moreNavigationController.topViewController where top.view.window != nil {
return topViewController(top)
} else if let selected = tab.selectedViewController {
return topViewController(selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(presented)
}
return base
}
}
Zastosowanie:
if let rootViewController = UIApplication.topViewController() {
//do sth with root view controller
}
Ta odpowiedź naprawiła irytujący problem z klasami przykładowych zaawansowanych operacji NSOperations firmy Apple. Jeśli wystąpił błąd, najwyższy kontroler widoku jest jedynym, który może wyświetlić alert. Mogłem zrobić iterację zamiast rekurencyjną, ponieważ jestem staroświecki, ale jest to znacznie lepsze niż ślepo za pomocą UIApplication.sharedApplication(). KeyWindow? .rootViewController –
Często muszę odzyskać kontrolera widoku, który jest aktualnie wyświetlany. Może to oznaczać kontroler widoku u góry stosu bieżącego kontrolera UINavigationController, aktualnie przedstawionego kontrolera widoku itd. Tak więc napisałem tę funkcję, która wylicza ją przez większość czasu i można ją wykorzystać w rozszerzeniu UIViewController.
kod w Swift 3:
func currentViewController(
_ viewController: UIViewController? =
UIApplication.shared.keyWindow?.rootViewController)
-> UIViewController? {
guard let viewController =
viewController else { return nil }
if let viewController =
viewController as? UINavigationController {
if let viewController =
viewController.visibleViewController {
return currentViewController(viewController)
} else {
return currentViewController(
viewController.topViewController)
}
} else if let viewController =
viewController as? UITabBarController {
if let viewControllers =
viewController.viewControllers,
viewControllers.count > 5,
viewController.selectedIndex >= 4 {
return currentViewController(
viewController.moreNavigationController)
} else {
return currentViewController(
viewController.selectedViewController)
}
} else if let viewController =
viewController.presentedViewController {
return viewController
} else if viewController.childViewControllers.count > 0 {
return viewController.childViewControllers[0]
} else {
return viewController
}
}
połączenia go z: currentViewController()
Man Szukałem wszędzie w tej sprawie. dzięki za tonę. –