ios - dismissViewControllerAnimated :completion: on iOS 8

标签 ios uiviewcontroller ios8 presentviewcontroller

在 iOS <= 7 中,直接在调用 dismissViewControllerAnimated:completion: 之后会导致 presentedViewControllernil。 在 iOS 8 中,presentedViewController 仍然指向呈现的 View Controller ,直到执行完成 block 。

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

所以在 iOS 8 中,我们不能依赖属性 presentedViewController 来找出哪个 View Controller 是当前可见的顶部 View Controller 。

在 iOS 8 中,警报需要显示在 View Controller 上(poses another problem)。如果我们尝试展示的 View Controller 已经展示了一个 View Controller ,它们将不会显示。

如果我只是关闭我呈现的 View Controller 并在当前顶部可见的 View Controller 上显示一个 UIAlertController(通过递归搜索最后一个 presentedViewController),那么它当然不会显示但记录一条错误消息:“警告:尝试呈现其 View 不在窗口层次结构中!”

  1. 这是 iOS 8 中的错误还是新方法?
  2. 我怎样才能找到可以显示我的 UIALertController 的 View Controller ?

最佳答案

我找到了一个解决方法来找出我可以在哪个 View Controller 上显示警报:

@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];

swift 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()
    }
}

关于ios - dismissViewControllerAnimated :completion: on iOS 8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26907411/

相关文章:

ios - 删除 iOS 应用设置

ios - UITapGestureRecognizer 在第一个选项卡中不起作用

ios - NewRelicAgent 框架在 NR_timeElapsedInMilliSeconds 内崩溃

ios - 如何正确识别一个典型事件

ios - 除了 Twilio 提供的教程之外,还有什么好的 Twilio iOS VOIP Client 教程吗?

swift - 无法从 didReceiveLocalNotification 重新加载 UITable

iphone - 如何覆盖 UIViewController 中的 "view"属性?

iOS:包裹在导航 Controller 中时将数据传递给模态 VC

objective-c - UINavigationBar 自定义字体不适用于 iOS 8

ios - UITableViewCell 中每个 WebView 的 ActivityIndi​​cator