Jak znaleźć kontroler widoku najwyższego poziomu na iOS
Natknąłem się teraz na kilka przypadków, w których wygodnie byłoby znaleźć kontroler widoku" najwyższego " (ten odpowiedzialny za bieżący widok), ale nie znalazłem sposobu, aby to zrobić.
W zasadzie wyzwanie jest takie: biorąc pod uwagę, że jeden jest Wykonywanie w klasie, która nie jest kontrolerem widoku (lub Widok) [i nie ma adresu aktywnego widoku] i nie został przekazany adres najwyższego kontrolera widoku (lub, powiedzmy, adres kontrolera nawigacji), czy można znaleźć ten kontroler widoku? (A jeśli tak, to w jaki sposób?)
Lub, jeśli nie, czy jest możliwe znalezienie najwyższego widoku?
5 answers
IOS 4 wprowadził właściwość rootViewController na UIWindow:
[UIApplication sharedApplication].keyWindow.rootViewController;
Po utworzeniu kontrolera widoku musisz go ustawić samodzielnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-25 21:42:11
Myślę, że potrzebujesz kombinacji zaakceptowanej odpowiedzi i @fishstix
+ (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
Swift 3.0+
func topMostController() -> UIViewController? {
guard let window = UIApplication.shared.keyWindow, let rootViewController = window.rootViewController else {
return nil
}
var topController = rootViewController
while let newTopController = topController.presentedViewController {
topController = newTopController
}
return topController
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-26 09:45:00
Aby uzupełnić odpowiedź Jonasga (który pominął Kontrolery paska tabulacji podczas przejazdu), oto moja wersja zwracania aktualnie widocznego kontrolera widoku:
- (UIViewController*)topViewController {
return [self topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}
- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController*)rootViewController;
return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
} else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController*)rootViewController;
return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
} else if (rootViewController.presentedViewController) {
UIViewController* presentedViewController = rootViewController.presentedViewController;
return [self topViewControllerWithRootViewController:presentedViewController];
} else {
return rootViewController;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:54
PEŁNA WERSJA Nie rekurencyjna, zajmująca się różnymi scenariuszami:
- kontroler widoku prezentuje inny widok
- kontroler widoku to
UINavigationController
- kontroler widoku to
UITabBarController
Objective-C
UIViewController *topViewController = self.window.rootViewController;
while (true)
{
if (topViewController.presentedViewController) {
topViewController = topViewController.presentedViewController;
} else if ([topViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *nav = (UINavigationController *)topViewController;
topViewController = nav.topViewController;
} else if ([topViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController *tab = (UITabBarController *)topViewController;
topViewController = tab.selectedViewController;
} else {
break;
}
}
Swift 4+
extension UIWindow {
func topViewController() -> UIViewController? {
var top = self.rootViewController
while true {
if let presented = top?.presentedViewController {
top = presented
} else if let nav = top as? UINavigationController {
top = nav.visibleViewController
} else if let tab = top as? UITabBarController {
top = tab.selectedViewController
} else {
break
}
}
return top
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-25 18:54:27
Uzyskanie najwyższego kontrolera widoku dla Swift przy użyciu rozszerzeń
Kod:
extension UIViewController {
@objc func topMostViewController() -> UIViewController {
// Handling Modal views
if let presentedViewController = self.presentedViewController {
return presentedViewController.topMostViewController()
}
// Handling UIViewController's added as subviews to some other views.
else {
for view in self.view.subviews
{
// Key property which most of us are unaware of / rarely use.
if let subViewController = view.next {
if subViewController is UIViewController {
let viewController = subViewController as! UIViewController
return viewController.topMostViewController()
}
}
}
return self
}
}
}
extension UITabBarController {
override func topMostViewController() -> UIViewController {
return self.selectedViewController!.topMostViewController()
}
}
extension UINavigationController {
override func topMostViewController() -> UIViewController {
return self.visibleViewController!.topMostViewController()
}
}
Użycie:
UIApplication.sharedApplication().keyWindow!.rootViewController!.topMostViewController()