我希望我的应用程序可以在用户每次使用时都跳转到第一个视图控制器。
因此,我想创建一个函数以解除所有视图控制器的显示,无论它们是在导航控制器中推送、以模态方式呈现还是打开任何方法。
我尝试了各种方法,但我没有成功地确保解除所有视图控制器的显示。 有没有简单的方法?
我希望我的应用程序可以在用户每次使用时都跳转到第一个视图控制器。
因此,我想创建一个函数以解除所有视图控制器的显示,无论它们是在导航控制器中推送、以模态方式呈现还是打开任何方法。
我尝试了各种方法,但我没有成功地确保解除所有视图控制器的显示。 有没有简单的方法?
试试这个:
self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)
它应该关闭所有在根视图控制器之上的视图控制器。
如果这样做不起作用,那么你可以像这样手动运行一个while循环来实现。
func dismissViewControllers() {
guard let vc = self.presentingViewController else { return }
while (vc.presentingViewController != nil) {
vc.dismiss(animated: true, completion: nil)
}
}
它将关闭所有视图控制器,直到它有一个presentingController。
编辑:如果您想要关闭/弹出已推入的视图控制器,可以使用
self.navigationController?.popToRootViewController(animated: true)
希望这有所帮助。
popToRootViewController
并解决了这个问题 :) - Byoth如果你正在使用导航,你可以使用第一个选项。如果你是以模态方式呈现,你可以使用第二个选项:
self.navigationController?.popToRootViewController(animated: true)
self.view.window!.rootViewController?.dismissViewControllerAnimated(false, completion: nil)
大家好,这里是 Swift-4 的答案。
如果要返回根视图控制器,您只需调用一行代码即可完成工作。
self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)
如果你有启动画面,然后是登录画面,如果你想要进入登录画面,你可以在上述代码中简单地附加 presentedviewcontroller。
self.view.window?.rootViewController?.presentedViewController!.dismiss(animated: true, completion: nil)
如果正在呈现视图控制器,只需请求您的rootViewController
将其关闭即可。
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.window?.rootViewController?.dismiss(animated: true, completion: nil)
(appDelegate.window?.rootViewController as? UINavigationController)?.popToRootViewController(animated: true)
}
popToRootViewController
解决了这个问题 :) - Byothself
引用当前呈现窗口时,这对我起作用 - somenickname根据您的视图控制器的层叠情况,返回到初始视图控制器的策略可能会有所不同。
可能会有多种情况,根据您的情况,您可以决定哪种方法是最好的。
情况1
这是一个简单的情况,在任何视图控制器中使用navigationController?.popToRootViewController(animated:true)
都能使你回到视图控制器A
情况2
这种情况可以通过上面的答案来解决self?.view.window?.rootViewController.dismiss(animated: true)
,这将会带你回到视图控制器A
情况3
现在想象一下,您需要从视图控制器E返回到A
使用上面的两个答案此时无法解决您的问题,因为如果导航控制器不在屏幕上,就不能弹出到根视图控制器。
您可以尝试添加计时器和监听器来关闭视图控制器,然后再弹出,这可能有效,我认为上面有一个函数dismissPopAllViewViewControllers
也是这样做的-但我注意到这会导致异常行为,并出现警告Unbalanced calls to begin/end appearance transitions for
我认为您可以采取以下方法来解决此类情况:
因此,我将上面的架构更改为:
let rootViewController = self?.view.window?.rootViewController as? UINavigationController
rootViewController?.setViewControllers([rootViewController!.viewControllers.first!],
animated: false)
rootViewController?.dismiss(animated: true, completion: nil)
没有任何警告,您将被传输回视图控制器 A。
您可以根据需求进行调整,但这是重置复杂视图控制器层次结构的概念。
// MARK:- Dismiss and Pop ViewControllers
func dismissPopAllViewViewControllers() {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.window?.rootViewController?.dismiss(animated: true, completion: nil)
(appDelegate.window?.rootViewController as? UINavigationController)?.popToRootViewController(animated: true)
}
}
Swift 5.4:
self.navigationController?.popToRootViewController(animated: true)
func popToRootViewController(animated: Bool)
但如果您想要前往特定的控制器,只需使用以下函数。
func popToViewController(UIViewController, animated: Bool)
弹出视图控制器,直到指定的视图控制器在导航栈的顶部。
let allControllers = NSMutableArray(array: navigationController!.viewControllers)
let vcCount = allControllers.count
for _ in 0 ..< vcCount - 2 {
allControllers.removeObject(at: 1)
}
// now, allControllers[0] is root VC, allControllers[1] is presently displayed VC. write back to nav stack
navigationController!.setViewControllers(allControllers as [AnyObject] as! [UIViewController], animated: false)
// then pop root VC
navigationController!.popViewController(animated: true)
查看this以了解如何进一步操作导航栈。如果您的最顶层VC是模态的,请先在上面的代码之前将其解除。
创建一个回 unwind Segue(您可以在https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/UsingSegues.html中找到,版权归属于 Apple Inc.)
Unwind Segue 允许您将已经呈现的视图控制器解除。通过将按钮或其他适当的对象链接到当前视图控制器的 Exit 对象,在界面构建器中创建回 Unwind Segue。当用户点击按钮或与适当的对象交互时,UIKit 会搜索视图控制器层次结构以查找能够处理回 Unwind Segue 的对象。然后它会关闭当前视图控制器和任何中间视图控制器,以显示回 Unwind Segue 的目标。
创建回 unwind Segue:
选择应该在回 unwind Segue 结束时出现在屏幕上的视图控制器。
在您选择的视图控制器上定义一个回 unwind 操作方法。
该方法的 Swift 语法如下:
@IBAction func myUnwindAction(unwindSegue: UIStoryboardSegue)
- (IBAction)myUnwindAction:(UIStoryboardSegue*)unwindSegue
3. 导航到发起取消动作的视图控制器。
在应该触发取消过渡的按钮(或其他对象)上按住 Control 键并单击。此元素应位于您想要关闭的视图控制器中。
将其拖动到视图控制器场景顶部的 Exit 对象上。
在尝试在Interface Builder中创建相应的取消转场之前,您必须在其中一个视图控制器中定义取消操作方法。该方法的存在是必需的,并告诉Interface Builder有一个有效的目标可用于取消转场。