уволитьViewControllerAnimated: завершение: на iOS 8

В iOS ‹= 7 сразу после вызова dismissViewControllerAnimated:completion: результатом будет presentedViewController, равное nil. В iOS 8 presentedViewController по-прежнему указывает на представленный контроллер представления до тех пор, пока не будет выполнен блок завершения.

[self dismissViewControllerAnimated:NO completion:^{
    //self.presentedViewController is nil
}];
//self.presentedViewController is nil on iOS 7, but not nil on iOS 8

Таким образом, в iOS 8 мы не можем полагаться на свойство presentedViewController, чтобы узнать, какой контроллер представления в настоящее время является самым видимым контроллером представления.

В iOS 8 оповещения должны быть представлены на контроллере представления (что создает другую проблему< /а>). Они не будут отображаться, если контроллер представления, который мы пытаемся представить, уже представляет контроллер представления.

Если я просто закрою свой представленный контроллер представления и покажу UIAlertController на верхнем видимом в данный момент контроллере представления (путем рекурсивного поиска последнего presentedViewController), то он, конечно, не покажет, но зарегистрирует сообщение об ошибке: «Предупреждение: попытка представить, чье представление не в иерархии окон!"

  1. Это ошибка в iOS 8 или просто новый способ?
  2. Как я могу узнать контроллер представления, на котором я могу представить свой UIALertController?

person fabb    schedule 13.11.2014    source источник
comment
isBeingDismissed немного помогает   -  person fabb    schedule 13.11.2014


Ответы (1)


Я нашел обходной путь, чтобы узнать, на каком контроллере представления я могу представить предупреждение:

@implementation UIViewController (visibleViewController)

- (UIViewController *)my_visibleViewController {

    if ([self isKindOfClass:[UINavigationController class]]) {
        // do not use method visibleViewController as the presentedViewController could beingDismissed
        return [[(UINavigationController *)self topViewController] my_visibleViewController];
    }

    if ([self isKindOfClass:[UITabBarController class]]) {
        return [[(UITabBarController *)self selectedViewController] my_visibleViewController];
    }

    if (self.presentedViewController == nil || self.presentedViewController.isBeingDismissed) {
        return self;
    }

    return [self.presentedViewController my_visibleViewController];
}

@end

// To show a UIAlertController, present on the following viewcontroller:
UIViewController *visibleViewController = [[UIApplication sharedApplication].delegate.window.rootViewController my_visibleViewController];

Свифт 3:

import UIKit

extension UIViewController {
    func visibleViewController() -> UIViewController? {
        guard !(self is UINavigationController) else {
            let navVC = self as! UINavigationController
            return navVC.topViewController?.visibleViewController()
        }

        guard !(self is UITabBarController) else {
            let tabVC = self as! UITabBarController
            return tabVC.selectedViewController?.visibleViewController()
        }

        if self.presentedViewController == nil || 
           self.presentedViewController!.isBeingDismissed {
            return self
        }

        return self.presentedViewController?.visibleViewController()
    }
}
person fabb    schedule 13.11.2014