关闭另一个控制器后如何显示一个新控制器?

how to make a show a new controller after closing another controller?

我是Swift的新手,想做一个简单的应用程序

当用户启动应用程序时,他会看到 FirstViewController 那里有 1 个登录按钮,当用户点击此按钮时,应用程序会呈现 SecondViewController 模态

SecondViewController 上有文本字段和一个“Auth 按钮”,我希望通过点击“Auth 按钮”,SecondViewController 被关闭,FirstViewController 显示ThirdViewController

好的,我使用 self.navigationController.show() 方法

let secondVC = SecondViewController()
self.navigationController.show(secondVC, sender: self)

和关闭方法 VC,但是当我在 dismiss 之后尝试打开 ThirdViewController 时,它不起作用

func buttonTapped() {
    let firstVC = FirstViewController()
    let thirdVC = ThirdViewController()
    firstVC.navigationController.show(thirdVC, sender: self)
    self.dismiss(animated: true, completion: nil)
    
}

如何正确操作?

我不使用故事板,如果它很重要

您是 “Swift”的“新手” ...您可能需要花更多时间学习基础知识,然后再尝试 “制作简单的应用程序".

问题是,在这一点上,你甚至不知道要问什么,或正确的术语。

比如你说:

  • “到达 FirstViewController” ...“到达”是什么意思?
  • “点击” 而不是“点击”
  • SecondViewController 关闭,FirstViewController 打开 ThirdViewController ...“关闭”和“打开”不明确条款

我不想听起来很刺耳,但你会在学习字母表之前尝试写小说吗?

但是,这是一个快速、非常简单的示例...

我们从 FirstViewController 作为根控制器开始...点击按钮显示 SecondViewController 并设置一个闭包...该控制器中的点击按钮调用闭包,此时我们通过用户输入字符串并将根控制器替换为 ThirdViewController:

class FirstViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemRed
        
        // create a "Login" button
        let btn = UIButton()
        btn.backgroundColor = .darkGray
        btn.setTitleColor(.white, for: .normal)
        btn.setTitleColor(.lightGray, for: .highlighted)
        btn.setTitle("Login", for: [])
        btn.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(btn)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            // center the button in the view
            btn.centerXAnchor.constraint(equalTo: g.centerXAnchor),
            btn.centerYAnchor.constraint(equalTo: g.centerYAnchor),
            btn.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.75),
            btn.heightAnchor.constraint(equalToConstant: 50.0),
        ])
        
        // add touchUpInside action
        btn.addTarget(self, action: #selector(loginBtnTapped(_:)), for: .touchUpInside)
    }
    
    @objc func loginBtnTapped(_ sender: Any?) -> Void {
        let secondVC = SecondViewController()
        
        // set the closure
        secondVC.theClosure = { [weak self] str1, str2 in
            guard let self = self else { return }
            
            // closure was called from SecondVC,
            //  dismiss it and then show ThirdVC
            self.dismiss(animated: true, completion: {
                let thirdVC = ThirdViewController()
                
                // set the strings
                thirdVC.val1 = str1
                thirdVC.val2 = str2
                
                // replace First VC with Third VC
                UIApplication.shared.windows.first?.rootViewController = thirdVC
                UIApplication.shared.windows.first?.makeKeyAndVisible()
            })
        }
        
        // present the second VC
        self.present(secondVC, animated: true, completion: nil)
    }
    
    
}

class SecondViewController: UIViewController {

    var theClosure: ((String, String) -> ())?
    
    let tf1 = UITextField()
    let tf2 = UITextField()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemGreen

        // stack view to arrange two fields and a button
        let stack = UIStackView()
        stack.axis = .vertical
        stack.spacing = 20
        stack.translatesAutoresizingMaskIntoConstraints = false

        // add text fields to stack view
        [tf1, tf2].forEach { tf in
            tf.borderStyle = .roundedRect
            stack.addArrangedSubview(tf)
        }
        
        // create an "Auth" button
        let btn = UIButton()
        btn.backgroundColor = .darkGray
        btn.setTitleColor(.white, for: .normal)
        btn.setTitleColor(.lightGray, for: .highlighted)
        btn.setTitle("Auth", for: [])
        
        // add button to stack view
        stack.addArrangedSubview(btn)

        view.addSubview(stack)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            // constrain stack view centered horizontally, near top
            stack.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
            stack.centerXAnchor.constraint(equalTo: g.centerXAnchor),
            stack.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.75),
            btn.heightAnchor.constraint(equalToConstant: 50.0),
        ])

        // add touchUpInside action
        btn.addTarget(self, action: #selector(authBtnTapped(_:)), for: .touchUpInside)
    }
    
    @objc func authBtnTapped(_ sender: Any?) -> Void {
        // get the text from the two fields
        var s1 = tf1.text ?? ""
        var s2 = tf2.text ?? ""
        if s1.isEmpty { s1 = "Field 1 Empty" }
        if s2.isEmpty { s2 = "Field 2 Empty" }

        // call the closure with the two strings
        theClosure?(s1, s2)
    }

}

class ThirdViewController: UIViewController {
    
    var val1: String = ""
    var val2: String = ""

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBlue
        
        // create a multi-line label
        let label = UILabel()
        label.backgroundColor = .cyan
        label.numberOfLines = 0
        label.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(label)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            // constrain the label centered in the view
            label.centerXAnchor.constraint(equalTo: g.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: g.centerYAnchor),
            label.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.75),
        ])

        // set label text
        var s: String = "User-entered strings:"
        s += "\n\n"
        s += val1
        s += "\n\n"
        s += val2

        label.text = s
    }
    
}