如何通过使用Swift单击完成按钮来关闭以前的和当前的视图控制器

时间:2019-08-28 20:03:35

标签: ios swift

我有三个视图控制器(VC1, VC2, VC3)。在这里,单击VC1添加按钮以显示VC2,然后单击VC2,我还有另一个添加按钮用于显示VC3。 VC3我有导航栏canceldone按钮。如果单击“我可以关闭并显示VC2”,但是如果单击“完成”按钮,则需要显示VC1(在VC1和VC3之间需要关闭VC2)。如何实现呢?

我正在使用下面的代码来显示和关闭

VC1

@IBAction func presentFirst(_ sender: Any) {
    let firstvc = self.storyboard?.instantiateViewController(withIdentifier: "firstcontroller") as! FirstViewController
    let navigationController = UINavigationController(rootViewController: firstvc)
    self.present(navigationController, animated: true, completion: nil)
}

VC2

 @IBAction func presentSecond(_ sender: Any) {
        let secondtvc = self.storyboard?.instantiateViewController(withIdentifier: "secondcontroller") as! SecondViewController
        let navigationController = UINavigationController(rootViewController: secondtvc)
        self.present(navigationController, animated: true, completion: nil)
    }



     @IBAction func doneAction(_ sender: Any) {
            self.dismiss(animated: true, completion: nil)
        }

        @IBAction func cancelAction(_ sender: Any) {
            self.dismiss(animated: true, completion: nil)
        }

VC3

@IBAction func doneAction(_ sender: Any) {
    // Need to dismiss current and previous VC2 
}

@IBAction func cancelAction(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
}

2 个答案:

答案 0 :(得分:1)

一个好的做法是在VC2上使用prepare(for segue:以便将其自身的引用发送到VC3,以便以后可以将其关闭。

  • 因此,首先在VC3中添加一个引用变量

    var vc2Ref: VC2!
    
  • 然后在VC2中,您可以像这样设置此变量的值

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc3 = segue.destination as? VC3 {
            vc3.vc2Ref = self
        }
    }
    
  • 现在您可以关闭VC2和VC3

    @IBAction func doneAction(_ sender: Any) {
        //dismiss current VC3
        self.dismiss(animated: true, completion: nil)
        //dismiss previous VC2 
        self.vc2Ref.dismiss(animated: true, completion: nil)
    }
    

答案 1 :(得分:0)

关于dismiss() method document

  

讨论

     

如果您连续显示多个视图控制器,从而构建了一个显示的视图控制器堆栈,则在堆栈中较低的视图控制器上调用此方法将取消其直接子视图控制器以及该堆栈上该子视图之上的所有视图控制器。发生这种情况时,只有最上面的视图会以动画方式关闭;只需从堆栈中删除所有中间视图控制器即可。最顶层的视图使用其模式转换样式关闭,该样式过渡样式可能与堆栈中较低的其他视图控制器使用的样式有所不同。

简而言之,如果显示的堆栈如下,

A -> B -> C -> D -> E

// A.present(B), then B.present(C), ... , D.present(E) 
// E is top-most view controller.

如果调用E.dismiss(),则堆栈将为

A -> B -> C -> D

然后,如果调用C.dismiss(),则堆栈将为

A -> B

// NOTE:
// Don't call `E.dismiss()`, `D.dismiss()`, `C.dismiss()` in sequence.
// ONLY call `C.dismiss()`. Just as the `Discussion` said.