使用 Swift 中的协议将值从一个视图反转为另一个视图

Reverse value from one view to another by using protocol in Swift

现在我正在学习 swift 编程并且我被协议语法困住了。

我想实现一个简单的功能:我在一个 ViewController 中创建了两个 Main.Storyboard,第一个 ViewController 有一个标签和一个按钮到第二个 ViewController。第二个有一个文本字段和一个返回到第一个 ViewController 的按钮。

我在 textField 中输入了一些词并单击返回按钮关闭视图,但在第一个视图中我看不到标签发生了变化。

这是我为委托视图编写的代码:

import UIKit

protocol SecondViewDelegate {
    func getText(text: String)
}

class SecondViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var textField: UITextField!

    var text: String?
    var delegate: SecondViewDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
    }

    @IBAction func backButton(_ sender: UIButton) {
//        print(text!)
        delegate?.getText(text: text!)
        dismiss(animated: true, completion: nil)
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
//        print("textFieldDidEndEditing has been called")
        text = textField.text
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.endEditing(true)
        return true
    }
}

我在按下后退按钮时打印了文本,我确定控制台上打印的文本就是我在文本字段中输入的文本。

这是显示文本的另一个视图的代码:

class ViewController: UIViewController, SecondViewDelegate {

    @IBOutlet weak var textLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        let secondVC = SecondViewController()
        secondVC.delegate = self
    }

    @IBAction func clickButton(_ sender: UIButton) {
        performSegue(withIdentifier: "goToSecond", sender: self)
    }

    func getText(text: String) {
        self.textLabel.text = text
    }

}

当我返回视图时,标签没有改变。我在函数 getText 和 运行 应用程序中添加了一个断点,应用程序没有崩溃。

我不知道我哪里做错了。谁能指出问题来帮助我?谢谢!

在您的第一个视图控制器中,如果您使用 segues 转到第二个视图控制器,则需要在 prepareForSegue 方法中设置 delegates。当前,您正在 viewDidLoad 中创建一个新对象并将委托分配给它,这是错误的。

解决方法如下:

class ViewController: UIViewController, SecondViewDelegate {

    @IBOutlet weak var textLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    @IBAction func clickButton(_ sender: UIButton) {
        performSegue(withIdentifier: "goToSecond", sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goToSecond" {
            if let vc = segue.destination as? SecondViewController {
                vc.delegate = self 
            }
        }
    }

    func getText(text: String) {
        self.textLabel.text = text
    }

}

请将此方法添加到您的传递委托代码中。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "goToSecond" {
        if let vc = segue.destination as? SecondViewController {
            vc.delegate = self 
        }
    }
}

并删除这行代码。

let secondVC = SecondViewController()
secondVC.delegate = self