关闭所有打开的视图控制器的单一功能
single function to dismiss all open view controllers
我有一个单视图应用程序。我有一个导航控制器链接到根视图控制器的所有子控制器。
在每个子控制器中,我都有一个注销按钮。我想知道我是否可以有一个我可以调用的函数,它将关闭一路上打开的所有控制器,无论用户按下注销时当前打开的是哪个控制器?
我的基本起点:
func tryLogout(){
self.dismissViewControllerAnimated(true, completion: nil)
let navigationController = UINavigationController(rootViewController: UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("LoginViewController") )
self.presentViewController(navigationController, animated: true, completion: nil)
}
我正在寻找执行此任务的内存效率最高的方法。我会将我的注销功能放在一个单独的 utils 文件中,但是我不能使用 self.而且我仍然不知道要动态关闭哪个控制器。
更新
已建议弹出到根视图控制器。所以我的尝试是这样的:
func tryLogout(ViewController : UIViewController){
print("do something")
dispatch_async(dispatch_get_main_queue(), {
ViewController.navigationController?.popToRootViewControllerAnimated(true)
return
})
}
这是实现我所追求目标的最佳方式吗?
您可以致电:
self.view.window!.rootViewController?.dismiss(animated: false, completion: nil)
应该关闭根视图控制器之上的所有视图控制器。
看看放松转场是如何工作的。它超级简单,即使它包含复杂的导航(嵌套的推送和/或呈现的视图控制器),也可以让您 dismiss/pop 到层次结构中的某个 viewcontroller,无需太多代码。
这是一个非常好的答案(来自 smilebot),它展示了如何使用 unwind segues 来解决你的问题
斯威夫特3
navigationController?.popToRootViewControllerAnimated(true)
更新了 Swift 4 和 swift 5
的答案
UIApplication.shared.keyWindow?.rootViewController?.dismiss(animated: true, completion: nil)
以及当您使用 navigationController 时
self.navigationController?.popToRootViewController(animated: true)
适用于 Swift 3.0 +
self.view.window!.rootViewController?.dismiss(animated: true, completion: nil)
适用于 Swift 4 和 Swift 5
为了消除任何不需要的残留模态视图控制器,我使用了它并且在不保留任何导航堆栈引用的情况下运行良好。
UIApplication.shared.keyWindow?.rootViewController?.dismiss(animated: false, completion: nil)
self.view.window!
在我的案例中确实崩溃了,可能是因为它是模态屏幕并且丢失了对 window.
的引用
Swift
使用它直接跳转到您的 ROOT 导航控制器。
self.navigationController?.popToRootViewController(animated: true)
如果您有自定义 UITabbarController,请尝试通过以下方式关闭 UITabbarController 中的顶部 viewController:
class MainTabBarController: UITabBarController {
func aFuncLikeLogout() {
self.presentedViewController?.dismiss(animated: false, completion: nil)
//......
}
}
关闭所有模态视图。
Swift 5
view.window?.rootViewController?.dismiss(animated: true, completion: nil)
我想出了一个通用函数来使用完成块关闭所有呈现的控制器。
extension UIWindow {
static func keyWindow() -> UIWindow? {
UIApplication.shared.windows.filter({ [=10=].isKeyWindow }).first
}
}
func getVisibleViewController(_ rootViewController: UIViewController?) -> UIViewController? {
var rootVC = rootViewController
if rootVC == nil {
rootVC = UIWindow.keyWindow()?.rootViewController
}
var presented = rootVC?.presentedViewController
if rootVC?.presentedViewController == nil {
if let isTab = rootVC?.isKind(of: UITabBarController.self), let isNav = rootVC?.isKind(of: UINavigationController.self) {
if !isTab && !isNav {
return rootVC
}
presented = rootVC
} else {
return rootVC
}
}
if let presented = presented {
if presented.isKind(of: UINavigationController.self) {
if let navigationController = presented as? UINavigationController {
return navigationController.viewControllers.last!
}
}
if presented.isKind(of: UITabBarController.self) {
if let tabBarController = presented as? UITabBarController {
if let navigationController = tabBarController.selectedViewController! as? UINavigationController {
return navigationController.viewControllers.last!
} else {
return tabBarController.selectedViewController!
}
}
}
return getVisibleViewController(presented)
}
return nil
}
func dismissedAllAlert(completion: (() -> Void)? = nil) {
if let alert = UIViewController.getVisibleViewController(nil) {
// If you want to dismiss a specific kind of presented controller then
// comment upper line and uncomment below one
// if let alert = UIViewController.getVisibleViewController(nil) as? UIAlertController {
alert.dismiss(animated: true) {
self.dismissedAllAlert(completion: completion)
}
} else {
completion?()
}
}
注意:你可以在代码中的任何地方调用任何地方class
使用:-
dismissedAllAlert() // For dismiss all presented controller
dismissedAllAlert { // For dismiss all presented controller with completion block
// your code
}
我有一个单视图应用程序。我有一个导航控制器链接到根视图控制器的所有子控制器。
在每个子控制器中,我都有一个注销按钮。我想知道我是否可以有一个我可以调用的函数,它将关闭一路上打开的所有控制器,无论用户按下注销时当前打开的是哪个控制器?
我的基本起点:
func tryLogout(){
self.dismissViewControllerAnimated(true, completion: nil)
let navigationController = UINavigationController(rootViewController: UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("LoginViewController") )
self.presentViewController(navigationController, animated: true, completion: nil)
}
我正在寻找执行此任务的内存效率最高的方法。我会将我的注销功能放在一个单独的 utils 文件中,但是我不能使用 self.而且我仍然不知道要动态关闭哪个控制器。
更新 已建议弹出到根视图控制器。所以我的尝试是这样的:
func tryLogout(ViewController : UIViewController){
print("do something")
dispatch_async(dispatch_get_main_queue(), {
ViewController.navigationController?.popToRootViewControllerAnimated(true)
return
})
}
这是实现我所追求目标的最佳方式吗?
您可以致电:
self.view.window!.rootViewController?.dismiss(animated: false, completion: nil)
应该关闭根视图控制器之上的所有视图控制器。
看看放松转场是如何工作的。它超级简单,即使它包含复杂的导航(嵌套的推送和/或呈现的视图控制器),也可以让您 dismiss/pop 到层次结构中的某个 viewcontroller,无需太多代码。
这是一个非常好的答案(来自 smilebot),它展示了如何使用 unwind segues 来解决你的问题
斯威夫特3
navigationController?.popToRootViewControllerAnimated(true)
更新了 Swift 4 和 swift 5
的答案UIApplication.shared.keyWindow?.rootViewController?.dismiss(animated: true, completion: nil)
以及当您使用 navigationController 时
self.navigationController?.popToRootViewController(animated: true)
适用于 Swift 3.0 +
self.view.window!.rootViewController?.dismiss(animated: true, completion: nil)
适用于 Swift 4 和 Swift 5
为了消除任何不需要的残留模态视图控制器,我使用了它并且在不保留任何导航堆栈引用的情况下运行良好。
UIApplication.shared.keyWindow?.rootViewController?.dismiss(animated: false, completion: nil)
self.view.window!
在我的案例中确实崩溃了,可能是因为它是模态屏幕并且丢失了对 window.
Swift 使用它直接跳转到您的 ROOT 导航控制器。
self.navigationController?.popToRootViewController(animated: true)
如果您有自定义 UITabbarController,请尝试通过以下方式关闭 UITabbarController 中的顶部 viewController:
class MainTabBarController: UITabBarController {
func aFuncLikeLogout() {
self.presentedViewController?.dismiss(animated: false, completion: nil)
//......
}
}
关闭所有模态视图。
Swift 5
view.window?.rootViewController?.dismiss(animated: true, completion: nil)
我想出了一个通用函数来使用完成块关闭所有呈现的控制器。
extension UIWindow {
static func keyWindow() -> UIWindow? {
UIApplication.shared.windows.filter({ [=10=].isKeyWindow }).first
}
}
func getVisibleViewController(_ rootViewController: UIViewController?) -> UIViewController? {
var rootVC = rootViewController
if rootVC == nil {
rootVC = UIWindow.keyWindow()?.rootViewController
}
var presented = rootVC?.presentedViewController
if rootVC?.presentedViewController == nil {
if let isTab = rootVC?.isKind(of: UITabBarController.self), let isNav = rootVC?.isKind(of: UINavigationController.self) {
if !isTab && !isNav {
return rootVC
}
presented = rootVC
} else {
return rootVC
}
}
if let presented = presented {
if presented.isKind(of: UINavigationController.self) {
if let navigationController = presented as? UINavigationController {
return navigationController.viewControllers.last!
}
}
if presented.isKind(of: UITabBarController.self) {
if let tabBarController = presented as? UITabBarController {
if let navigationController = tabBarController.selectedViewController! as? UINavigationController {
return navigationController.viewControllers.last!
} else {
return tabBarController.selectedViewController!
}
}
}
return getVisibleViewController(presented)
}
return nil
}
func dismissedAllAlert(completion: (() -> Void)? = nil) {
if let alert = UIViewController.getVisibleViewController(nil) {
// If you want to dismiss a specific kind of presented controller then
// comment upper line and uncomment below one
// if let alert = UIViewController.getVisibleViewController(nil) as? UIAlertController {
alert.dismiss(animated: true) {
self.dismissedAllAlert(completion: completion)
}
} else {
completion?()
}
}
注意:你可以在代码中的任何地方调用任何地方class
使用:-
dismissedAllAlert() // For dismiss all presented controller
dismissedAllAlert { // For dismiss all presented controller with completion block
// your code
}