【问题标题】:how to make a show a new controller after closing another controller?关闭另一个控制器后如何制作一个新控制器?
【发布时间】:2022-01-11 07:50:44
【问题描述】:

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

当用户启动应用程序时,他会看到FirstViewController,其中有 1 个登录按钮,当用户点击此按钮时,应用程序会模态显示SecondViewController

SecondViewController 上有文本字段和“身份验证按钮”,我希望通过点击“身份验证按钮”,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)
    
}

怎么做才对?

如果它很重要,我不使用情节提要

【问题讨论】:

  • 欢迎来到 SO。您可能想查看How to Ask 以了解哪些类型的问题在这里成功。一般来说,您希望展示您所做的某种尝试以及您遇到的问题,而不是仅仅列出您想要的内容并询问方向。
  • @jnpdx 老实说,我没有任何代码,当然我可以编写 3 个 swift 文件,但除了有用的信息之外,还有更多不必要的信息。我正在使用let vc = SecondViewController()self.show (vc, sender: self),然后我不知道该怎么办。我需要通过单击SecondViewController 上的按钮将其关闭,然后显示thirdViewController。我尝试在firstViewController() 中创建一个方法func showThird() { vc = ThirdViewController(); self.show(vc, sender: self)
  • 当用户点击secondViewController上的Login按钮时,使用了dismiss方法,之后,创建了FirstViewController的实例,并试图在他身上调用这个方法,但什么也没发生

标签: ios swift xcode viewcontroller dismissviewcontroller


【解决方案1】:

您是“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
    }
    
}

【讨论】:

  • 您的示例效果很好,谢谢!术语不正确造成的误解不是因为我不了解基础知识,而是因为我的母语与英语有很大不同,而我目前不得不使用翻译来提问。我唯一想做的就是不改变rootViewController,代码怎么改进?
  • @Resly34 - "无需更改 rootViewController" ...有 许多 方法,但您没有t 说了有关您的应用程序结构的任何信息。你在 NavigationController 堆栈中吗?你需要FirstViewController 做其他事情吗?如果没有,您可以隐藏/删除“登录”按钮并添加/显示本来在 ThirdViewController 中的 UI 元素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-07
  • 1970-01-01
  • 2019-12-09
相关资源
最近更新 更多