从另一个 class 调用警报视图,但一个不在层次结构中
Calling alert view from another class, but one is not in hierarchy
我正在尝试从视图控制器中的一个 class 调用函数:
var rate = RateMyApp.sharedInstance
rate.showRatingAlert()
并在 RateMyApp class 中调用警报视图:
var window: AnyObject = UIApplication.sharedApplication().keyWindow!;
var vc = window.rootViewController;
vc?!.presentViewController(alert, animated: true, completion: nil)
但是,没有显示警报,有一种警告:
Warning: Attempt to present <UIAlertController: 0x15fe3dcf0> on <drawtext.ViewController: 0x16002a800> whose view is not in the window hierarchy!
这种情况时有发生,如果隐藏应用程序然后再次打开它几次,有时会显示警告。
什么会导致这种奇怪的行为?
在 window 启动时执行此操作
dispatch_async(dispatch_get_main_queue(), {
var window: AnyObject = UIApplication.sharedApplication().keyWindow!;
var vc = window.rootViewController;
vc?!.presentViewController(alert, animated: true, completion: nil)
})
按照我的想法你只需要
置顶viewcontroller[当前显示]
发出警报。
获取最顶层的视图控制器
[这是 obj C 代码。请努力在swift]
转换
-(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;
}
}
然后
UIViewController *topController = [self topViewController];
现在在 topController 上显示您的警报。
抱歉,我无法为您提供 Swift 代码。但希望这足以提示。
似乎已解决:
var window = UIApplication.sharedApplication().keyWindow!
// var vc = window.rootViewController!!.presentingViewController
var vc = window.rootViewController;
while (vc!.presentedViewController != nil)
{
vc = vc!.presentedViewController;
}
vc?.presentViewController(alert, animated: true, completion: nil)
看起来像 Chetan 的解决方案
在使用 UIAlertController 时,它应该显示在视图层次结构的最顶层 ViewController。
所以我建议:
var rate = RateMyApp.sharedInstance
rate.showRatingAlert(self)
在 RateMyApp class:
func showRatingAlert(sender:UIViewController){
//..... your UIAlertController here
sender.presentViewController(alert, animated: true, completion: nil)
}
一般来说,函数 presentViewController(:_)
应该只从最顶层的视图控制器调用。
您可以像这样为其创建扩展:
extension UIViewController {
@warn_unused_result
static func topViewController(base: UIViewController? = UIApplication.sharedApplication().windows.first?.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)
}
if let splitVC = base as? UISplitViewController {
if let lastVC = splitVC.viewControllers.last {
return topViewController(lastVC)
}
else {
return splitVC
}
}
if let lastChildVC = base?.childViewControllers.last {
return topViewController(lastChildVC)
}
return base
}
}
您可以按如下方式调用警报:
func showRatingAlert() {
if let vc = UIViewController.topViewController() {
vc.presentViewController(alert, animated: true, completion: nil)
}
}
我正在尝试从视图控制器中的一个 class 调用函数:
var rate = RateMyApp.sharedInstance
rate.showRatingAlert()
并在 RateMyApp class 中调用警报视图:
var window: AnyObject = UIApplication.sharedApplication().keyWindow!;
var vc = window.rootViewController;
vc?!.presentViewController(alert, animated: true, completion: nil)
但是,没有显示警报,有一种警告:
Warning: Attempt to present <UIAlertController: 0x15fe3dcf0> on <drawtext.ViewController: 0x16002a800> whose view is not in the window hierarchy!
这种情况时有发生,如果隐藏应用程序然后再次打开它几次,有时会显示警告。
什么会导致这种奇怪的行为?
在 window 启动时执行此操作
dispatch_async(dispatch_get_main_queue(), {
var window: AnyObject = UIApplication.sharedApplication().keyWindow!;
var vc = window.rootViewController;
vc?!.presentViewController(alert, animated: true, completion: nil)
})
按照我的想法你只需要
置顶viewcontroller[当前显示]
发出警报。
获取最顶层的视图控制器
[这是 obj C 代码。请努力在swift]
转换-(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;
}
}
然后
UIViewController *topController = [self topViewController];
现在在 topController 上显示您的警报。
抱歉,我无法为您提供 Swift 代码。但希望这足以提示。
似乎已解决:
var window = UIApplication.sharedApplication().keyWindow!
// var vc = window.rootViewController!!.presentingViewController
var vc = window.rootViewController;
while (vc!.presentedViewController != nil)
{
vc = vc!.presentedViewController;
}
vc?.presentViewController(alert, animated: true, completion: nil)
看起来像 Chetan 的解决方案
在使用 UIAlertController 时,它应该显示在视图层次结构的最顶层 ViewController。
所以我建议:
var rate = RateMyApp.sharedInstance
rate.showRatingAlert(self)
在 RateMyApp class:
func showRatingAlert(sender:UIViewController){
//..... your UIAlertController here
sender.presentViewController(alert, animated: true, completion: nil)
}
一般来说,函数 presentViewController(:_)
应该只从最顶层的视图控制器调用。
您可以像这样为其创建扩展:
extension UIViewController {
@warn_unused_result
static func topViewController(base: UIViewController? = UIApplication.sharedApplication().windows.first?.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)
}
if let splitVC = base as? UISplitViewController {
if let lastVC = splitVC.viewControllers.last {
return topViewController(lastVC)
}
else {
return splitVC
}
}
if let lastChildVC = base?.childViewControllers.last {
return topViewController(lastChildVC)
}
return base
}
}
您可以按如下方式调用警报:
func showRatingAlert() {
if let vc = UIViewController.topViewController() {
vc.presentViewController(alert, animated: true, completion: nil)
}
}