it-swarm.com.ru

Текущий вид контроллера из AppDelegate?

Есть ли способ получить текущий контроллер вида из AppDelegate? Я знаю, что есть rootViewController, но это не то, что я ищу.

47
aoakenfo

Если у вас есть UINavigationController в appDelegate, то используйте его свойство topViewController или visibleViewController

20
beryllium

Если контроллер представления вашего приложения является UINavigationController, вы можете сделать это:

((UINavigationController*)appDelegate.window.rootViewController).visibleViewController;

Точно так же, если это UITabBarController, вы можете сделать это:

((UITabBarController*)appDelegate.window.rootViewController).selectedViewController;

Конечно, явное приведение типа этого грязно. Лучше было бы захватить ссылку самостоятельно, используя сильные типы.

60
devios1

Это может помочь

- (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];
}

Swift версия:

extension UIApplication {
    class func topViewController(base: UIViewController? = UIApplication.shared.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
    }
}

Взято из: https://Gist.github.com/snikch/3661188

25
Daniel Ryan

сделать расширение:

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

Использование:

if let rootViewController = UIApplication.topViewController() {
    //do sth with root view controller
}
13
A.G

Получите объект appDelegate:

MyAppDelegate *tmpDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];

Как предположил Бериллий, вы можете использовать свойства UINavigationController для доступа к вашему текущему контроллеру представления.

Таким образом, код будет выглядеть так:

id myCurrentController = tmpDelegate.myNavigationController.topViewController;

или же:

NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;
11
Quasar

Вы можете получить текущий контроллер представления от rootViewController, ища его представленный ViewController, как это:

UIViewController *parentViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;

while (parentViewController.presentedViewController != nil){
    parentViewController = parentViewController.presentedViewController;
}
UIViewController *currentViewController = parentViewController;

Это работает со мной. Надеюсь, поможет :)

8
MattZ

Быстрое решение:

 self.window.rootViewController.presentedViewController. 

Это должно дать вам то, что вам нужно.

4
LevinsonTechnologies

Для любого not, использующего UINavigationController, но его контроллер представления по умолчанию - UIViewController, вы можете проверить, какой контроллер представления активен (или представлен), в 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)
}

Как вы можете видеть, я проверяю текущий контроллер представления, чтобы поддерживать различные ориентации интерфейса для определенных контроллеров представления. Для всех, кто заинтересован в использовании этого метода для поддержки конкретных, в каждом контроллере представления, который нуждается в определенной ориентации, должно быть размещено следующее.

override func supportedInterfaceOrientations() -> Int {
    return Int(UIInterfaceOrientationMask.All.rawValue)
} 

Примечание: Этот код был написан с Swift 1.2

4
Clay Ellis

Часто мне нужно получить контроллер представления, который отображается в данный момент. Это может означать контроллер представления в верхней части стека текущего UINavigationController, представленный в настоящее время контроллер представления и т.д. Поэтому я написал эту функцию, которая выясняет это большую часть времени, и которую можно использовать внутри расширения UIViewController.

Код в 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
    }
}

Позвоните с помощью: currentViewController()

0
Paolo Musolino

Расширение UIApplication в Swift 4+ Синтаксис на основе Решение A.G

public extension UIApplication {

    class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
        if let nav = base as? UINavigationController {
            return topViewController(base: nav.visibleViewController)
        }
        if let tab = base as? UITabBarController {
            let moreNavigationController = tab.moreNavigationController

            if let top = moreNavigationController.topViewController, top.view.window != nil {
                return topViewController(base: top)
            } else if let selected = tab.selectedViewController {
                return topViewController(base: selected)
            }
        }
        if let presented = base?.presentedViewController {
            return topViewController(base: presented)
        }
        return base
    }
}

Пример использования:

if let rootViewController = UIApplication.topViewController() {
     //do something with rootViewController
}
0
Maverick