Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/106.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIAlertController下最上面的ViewController_Ios_Swift_Uiviewcontroller_Uialertcontroller - Fatal编程技术网

Ios UIAlertController下最上面的ViewController

Ios UIAlertController下最上面的ViewController,ios,swift,uiviewcontroller,uialertcontroller,Ios,Swift,Uiviewcontroller,Uialertcontroller,我正在使用以下扩展来查找。 如果出现警报,上述代码将给出UIAlertController。 如何在UIAlertController下获取俯视图控制器 您可以检查下一个viewController是否为UIAlertController,如果是,则返回其父视图。大概是这样的: if let presented = base as? UIAlertController { return base.presentingViewController } 在返回之前,将其添加到您使用的扩展中 已

我正在使用以下扩展来查找。 如果出现警报,上述代码将给出
UIAlertController

如何在
UIAlertController
下获取俯视图控制器

您可以检查下一个viewController是否为
UIAlertController
,如果是,则返回其父视图。大概是这样的:

if let presented = base as? UIAlertController {
  return base.presentingViewController
}
在返回之前,将其添加到您使用的扩展中

已更新

extension UIApplication {
   class func topViewController(base: UIViewController? =    (UIApplication.sharedApplication().delegate as! AppDelegate).window?.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)
      }

      if let alert = base as? UIAlertController {
         return alert.presentingViewController
      }

      return base
   }
}

您可以使用其
presentingViewController
属性获取
UIAlertController
的父控制器

extension UIApplication {
  class func topViewController(base: UIViewController? = (UIApplication.sharedApplication().delegate as! AppDelegate).window?.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 alert = base as? UIAlertController {
      if let presenting = alert.presentingViewController {
        return topViewController(base: presenting)
      }
    }
    if let presented = base?.presentedViewController {
      return topViewController(base: presented)
    }
    return base
  }
}

在您的代码中使用这些更改,而不是在XCode上测试。

我使用此扩展来获取UIAlertController下的最顶层视图控制器,基本上,我要做的是在找到一个UIAlertController时停止查找顶层视图控制器

extension UIApplication {

var topViewController: UIViewController? {
    var viewController = keyWindow?.rootViewController
    guard viewController != nil else { return nil }
    var presentedViewController = viewController?.presentedViewController
    while presentedViewController != nil, !(presentedViewController is UIAlertController) {
        switch presentedViewController {
        case let navagationController as UINavigationController:
            viewController = navagationController.viewControllers.last
        case let tabBarController as UITabBarController:
            viewController = tabBarController.selectedViewController
        default:
            viewController = viewController?.presentedViewController
        }
        presentedViewController = viewController?.presentedViewController
    }
    return viewController
}

}

我认为您希望在当前最上面的可见VC上推送一个新VC,即UIAlertController,然后此UIAlertController将立即消失,导致推送的新VC也被关闭。最后,你不能推一个新的VC

问题是,如果您新建一个UIAlertView,然后调用
show
,Cocoa Touch将初始化一个新窗口,其中rootViewController为UIApplicationRotationFollowerController,而当前的ViewController为UIAlertController。因此,您无法在UIAlertController下遍历最顶端的VC,因为它存在于另一个窗口中


因此,如果
topViewController
keyWindow?遍历.rootViewController
,找到
UIAlertController
,再次调用
topViewController
,但从
window
遍历所需内容,例如
(UIApplication.sharedApplication().delegate as!AppDelegate).window?.rootViewController

这是正确的:

    func firstApplicableViewController() -> UIViewController? {
        if (self is UITabBarController) {
            let tabBarController = self as? UITabBarController
            return tabBarController?.selectedViewController?.firstApplicableViewController()
        } else if (self is UINavigationController) {
            let navigationController = self as? UINavigationController
            return navigationController?.visibleViewController?.firstApplicableViewController()
        } else if (self is UIAlertController) {
            let presentingViewController: UIViewController = self.presentingViewController!
            return presentingViewController.firstApplicableViewController()
        } else if self.presentedViewController != nil {
            let presentedViewController: UIViewController = self.presentedViewController!
            if (presentedViewController is UIAlertController) {
                return self
            } else {
                return presentedViewController.firstApplicableViewController()
            }
        } else {
            return self
        }
    }

创建一个UIApplication扩展,如下所示,
UIApplication.topViewController()
将返回
UIAlertController

iOS 13+
扩展应用程序{
类func topViewController(控制器:UIViewController?=UIApplication.shared.windows.first?.rootViewController)->UIViewController{
如果让navigationController=控制器为?UINavigationController{
返回topViewController(控制器:navigationController.visibleViewController)
}
如果让tabController=控制器为UITabBarController{
如果let selected=tabController.selectedViewController{
返回topViewController(控制器:选定)
}
}
如果让呈现=控制器?.presentedViewController{
返回topViewController(控制器:显示)
}
如果let alert=控制器为UIAlertController{
如果让navigationController=alert.presentingViewController作为?UINavigationController{
返回navigationController.ViewController.last
}
return alert.presentingViewController
}
返回控制器
}
}
iOS 12-
扩展应用程序{
类func topViewController(控制器:UIViewController?=UIApplication.shared.keyWindow?.rootViewController)->UIViewController{
如果让navigationController=控制器为?UINavigationController{
返回topViewController(控制器:navigationController.visibleViewController)
}
如果让tabController=控制器为UITabBarController{
如果let selected=tabController.selectedViewController{
返回topViewController(控制器:选定)
}
}
如果让呈现=控制器?.presentedViewController{
返回topViewController(控制器:显示)
}
如果let alert=控制器为UIAlertController{
如果让navigationController=alert.presentingViewController作为?UINavigationController{
返回navigationController.ViewController.last
}
return alert.presentingViewController
}
返回控制器
}
}

base.parentViewController为nil:(不…base为UIAlertController。不是base?.presentedViewController你确定要将它放在
if let presented=base?.presentedViewController{
?我做了,调试程序没有输入这个if。但是当我添加if let presented=base as?UIAlertController时{它确实输入了。这意味着UIAlertController是base。base不是UIAlertController。而是base!。presentedViewController是我们只需要找出谁是UIAlertController ancestorIt进行无限递归。我们只需要找出谁是UIAlertController Ancestor抱歉,它是
UIAlertController
而不是
UIAlertViewController
。更新了我的答案。仍然是无限递归occurs@BrianOgden请确认您是否未使用任何第三方控制器作为您的
窗口。rootViewController
像任何侧菜单之类的东西一样?这里可能会找到好的答案:@Luda您解决了这个问题吗..您能提供此问题的代码吗?我还面临ame问题..谢谢!@SteveGear不幸的是我不记得了。请检查下面的答案