neb*_*ebs 21 modal-dialog presentmodalviewcontroller ios
有没有办法在不知道可见视图控制器视图是什么的情况下以模态方式呈现视图控制器?基本上有点像你会在任何时间点显示警报视图.
我希望能够做到这样的事情:
MyViewController *myVC = [[MyViewController alloc] init];
[myVC showModally];
Run Code Online (Sandbox Code Playgroud)
我希望能够从应用程序的任何位置调用此功能,并将其显示在顶部.我不想关心当前的视图控制器是什么.
我打算用它来显示登录提示.我不想使用警报视图,我也不希望在整个应用程序中都有登录演示代码.
有什么想法吗?或者有没有更好的方法来实现这一目标?我应该只实现自己的机制,只是在窗口顶部放置一个视图?
Jef*_*mas 29
那么,你可以跟随链.
从...开始[UIApplication sharedApplication].delegate.window.rootViewController.
在每个视图控制器上执行以下一系列测试.
如果[viewController isKindOfClass:[UINavigationController class]],那么继续[(UINavigationController *)viewController topViewController].
如果[viewController isKindOfClass:[UITabBarController class]],那么继续[(UITabBarController *)viewController selectedViewController].
如果[viewController presentedViewController],那么继续[viewController presentedViewController].
all*_*ire 20
我在Swift中的解决方案(灵感来自MartinMoizard的要点)
extension UIViewController {
func presentViewControllerFromVisibleViewController(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?) {
if let navigationController = self as? UINavigationController {
navigationController.topViewController?.presentViewControllerFromVisibleViewController(viewControllerToPresent, animated: flag, completion: completion)
} else if let tabBarController = self as? UITabBarController {
tabBarController.selectedViewController?.presentViewControllerFromVisibleViewController(viewControllerToPresent, animated: flag, completion: completion)
} else if let presentedViewController = presentedViewController {
presentedViewController.presentViewControllerFromVisibleViewController(viewControllerToPresent, animated: flag, completion: completion)
} else {
present(viewControllerToPresent, animated: flag, completion: completion)
}
}
}
Run Code Online (Sandbox Code Playgroud)
NSE*_*nal 10
此解决方案为您提供最顶层的视图控制器,以便您可以在呈现之前处理任何特殊条件.例如,您可能只想在最顶层视图控制器不是特定视图控制器时才显示视图控制器.
extension UIApplication {
/// The top most view controller
static var topMostViewController: UIViewController? {
return UIApplication.shared.keyWindow?.rootViewController?.visibleViewController
}
}
extension UIViewController {
/// The visible view controller from a given view controller
var visibleViewController: UIViewController? {
if let navigationController = self as? UINavigationController {
return navigationController.topViewController?.visibleViewController
} else if let tabBarController = self as? UITabBarController {
return tabBarController.selectedViewController?.visibleViewController
} else if let presentedViewController = presentedViewController {
return presentedViewController.visibleViewController
} else {
return self
}
}
}
Run Code Online (Sandbox Code Playgroud)
有了它,您可以从任何地方展示您的视图控制器,而无需知道最顶级的视图控制器是什么
UIApplication.topMostViewController?.present(viewController, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)
或仅在最顶层视图控制器不是特定视图控制器时显示视图控制器
if let topVC = UIApplication.topMostViewController, !(topVC is FullScreenAlertVC) {
topVC.present(viewController, animated: true, completion: nil)
}
Run Code Online (Sandbox Code Playgroud)
需要注意的一点是,如果当前正在显示UIAlertController,UIApplication.topMostViewController则会返回一个UIAlertController.在a之上呈现UIAlertController有奇怪的行为,应该避免.因此,您应该!(UIApplication.topMostViewController is UIAlertController)在呈现之前手动检查,或者添加一个else if案例以返回nil ifself is UIAlertController
extension UIViewController {
/// The visible view controller from a given view controller
var visibleViewController: UIViewController? {
if let navigationController = self as? UINavigationController {
return navigationController.topViewController?.visibleViewController
} else if let tabBarController = self as? UITabBarController {
return tabBarController.selectedViewController?.visibleViewController
} else if let presentedViewController = presentedViewController {
return presentedViewController.visibleViewController
} else if self is UIAlertController {
return nil
} else {
return self
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在app delegate中实现此代码:
AppDelegate.m
-(void)presentViewControllerFromVisibleController:(UIViewController *)toPresent
{
UIViewController *vc = self.window.rootViewController;
[vc presentViewController:toPresent animated:YES];
}
Run Code Online (Sandbox Code Playgroud)
AppDelegate.h
-(void)presentViewControllerFromVisibleViewController:(UIViewController *)toPresent;
Run Code Online (Sandbox Code Playgroud)
来自哪里
#import "AppDelegate.h"
...
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
[delegate presentViewControllerFromVisibleViewController:myViewControllerToPresent];
Run Code Online (Sandbox Code Playgroud)
在你的代表中,你得到的rootViewController是window.这将永远是可见的 - 它是一切的"父"控制者.