如何在Swift中关闭视图控制器?

244
我试图通过在 IBAction 中调用 dismissViewController 来关闭一个 Swift 中的 ViewController。
  @IBAction func cancel(sender: AnyObject) {
    self.dismissViewControllerAnimated(false, completion: nil)
    println("cancel")
}

@IBAction func done(sender: AnyObject) {
    self.dismissViewControllerAnimated(false, completion: nil)
    println("done")
}

随机Segue的图片

我可以在控制台输出中看到println消息,但是视图控制器从未被解除。可能问题是什么?


2
你是如何呈现视图控制器的? - dasdom
我通过设置一个segue - “show”来完成映射,详见附加的截图。 - rshankar
4
请使用 modal。如果使用 push,则应该用导航控制器的 pop 方法将其关闭。 - dasdom
20个回答

460

从您的图像中看起来,您是使用 push 方法呈现了 ViewController

dismissViewControllerAnimated 用于关闭使用 modal 呈现的 ViewControllers

Swift 2

navigationController.popViewControllerAnimated(true)

Swift 4

navigationController?.popViewController(animated: true)

dismiss(animated: true, completion: nil)

8
如何为“显示详情”segue 进行操作? - MoralCode
2
对于 Swift 2.2 ,navigationController!.popViewControllerAnimated(true) - swiftBoy
7
对于Swift 3中的navigationController!.popViewController(animated: true),其翻译为“导航控制器.popViewController(animated: true)方法弹出当前视图控制器并启用动画效果。” - Alex Trott

196

我有一个解决方案可以帮助你解决问题。如果你是通过 modal 方式呈现视图,请尝试使用以下代码来 dismiss 这个视图控制器:

Swift 3:

self.dismiss(animated: true, completion: nil)

或者

如果您使用“push”转场呈现视图

self.navigationController?.popViewController(animated: true)

1
谢谢,但结果仍然相同,它没有解除ViewController。 - rshankar
5
这与OP使用的方法有何不同? - dasdom
34
如果你不回答我的问题,对话就毫无意义。 - dasdom
_ = self.navigationController?.popViewController(animated: true) - valexa
对我来说,“dismiss”会将我带回到登录界面,在那之前,标签控制器被定义。 - Bob The Coder

22

如果你这样做,我猜你可能无法在控制台中获得println消息。

@IBAction func cancel(sender: AnyObject) {
  if(self.presentingViewController){
    self.dismissViewControllerAnimated(false, completion: nil)
    println("cancel")
   }
}

@IBAction func done(sender: AnyObject) {
  if(self.presentingViewController){
    self.dismissViewControllerAnimated(false, completion: nil)
    println("done")
  }    
}

1
有关编程的内容翻译成中文:http://stackoverflow.com/questions/30840235/cant-dismiss-my-previous-alertcontroller-completely。有帮助的话,请帮忙解决一下,我已经卡在这里很久了,还是找不到解决方案。 - Thiha Aung

20

在Swift 3.0到4.0中,只需将以下内容输入您的函数即可:

self.dismiss(animated: true, completion: nil)

或者如果您在导航控制器中,您可以“pop”它:

self.navigationController?.popViewController(animated: true)

无法使用dismiss,因为我正在使用pushViewController。只有self.navigationController?.popViewController(animated: true)可用。 - Naresh

15
  1. 将您想要关闭的视图嵌入导航控制器中
  2. 添加一个标识为“完成”的 BarButton
  3. 选择“完成”按钮并调用助理编辑器
  4. 为此按钮创建 IBAction
  5. 将以下行添加到括号中:

    self.dismissViewControllerAnimated(true, completion: nil)
    

15

使用:

self.dismiss(animated: true, completion: nil)

与其:

self.navigationController.dismissViewControllerAnimated(true, completion: nil)

2
在 navigationController 后面加上 !,这对我有效。 - Jason G
2
请注意,如果navigationController为nil并且您使用了!,应用程序将崩溃。 - jobima

12

来自Apple 文档:

呈现视图控制器应负责关闭它所呈现的视图控制器。

因此,从自身调用dismiss方法是一个不好的做法。

如果您正在以模态方式呈现它,应该这样做:

presentingViewController?.dismiss(animated: true, completion: nil)

11

如果您在没有导航控制器的情况下呈现控制器,可以从呈现的控制器的方法中调用以下代码。

self.presentingViewController?.dismiss(animated: true, completion: nil)

如果您的ViewController是以模态形式呈现的,那么可选的presentingViewController将不为nil,代码将被执行。


7

根据我的经验,我为UIViewController添加了一个方法,可以将扩展程序中的我取消:

extension UIViewController {
    func dismissMe(animated: Bool, completion: (()->())?) {
        var count = 0
        if let c = self.navigationController?.viewControllers.count {
            count = c
        }
        if count > 1 {
            self.navigationController?.popViewController(animated: animated)
            if let handler = completion {
                handler()
            }
        } else {
            dismiss(animated: animated, completion: completion)
        }
    }
}

然后我在任何UIViewController子类中调用此方法来关闭视图控制器。例如,在取消操作中:

class MyViewController: UIViewController {
   ...
   @IBAction func cancel(sender: AnyObject) {
     dismissMe(animated: true, completion: nil)
   }
   ...
}

6
所以如果你想要关闭你的视图控制器,请使用以下代码。此代码编写在按钮动作中以关闭 VC。
  @IBAction func cancel(sender: AnyObject) {
   dismiss(animated: true, completion: nil)
  }

1
虽然这段代码片段可能解决了问题,但是包括解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,而这些人可能不知道您的代码建议的原因。 - DimaSan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接