繁体   English   中英

为什么我必须调用我的协议函数两次才能使其工作?

[英]Why do I have to call my protocol functions two times to make it work?

我目前正在构建一个简单的应用程序来学习协议 - 委托功能。 然而,我的代码不起作用,即使我按照我在第一个练习应用程序中所做的方式进行了编辑。 FirstViewController中有一个UILabel和一个UIButton 当用户点击UIButton时,一个 segue 将他们带到SecondViewController ,他们应该在其中将他们的名字输入到UITextField中。 之后,他们可以在UIButton中按SecondViewController ,输入的名称应该显示在FirstViewControllerUILabel中。

我不明白为什么我必须在@IBAction backButtonPresses()中调用协议 function 两次。 另外,我无法弄清楚如何在 FirstViewController 中处理相同的协议FirstViewController

这是FirstViewController.swift文件的代码:

import UIKit

class FirstViewController: UIViewController, SecondViewControllerDelegate {
    
    
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var button: UIButton!
    
    var labelText = ""
    let secondVC = SecondViewController()
    
    
    func changeLabelText(name: String) {
        labelText = secondVC.enteredName
    }
    
    
    @IBAction func buttonPressed(_ sender: UIButton) {
        performSegue(withIdentifier: "goToSecondVC", sender: self)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let destinationVC = segue.destination as? SecondViewController
        destinationVC?.delegate = self
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        nameLabel.text = secondVC.enteredName
    }
    
}

这是secondViewController的代码:

import UIKit

protocol SecondViewControllerDelegate {
    func changeLabelText(name: String)
}

class SecondViewController: UIViewController, SecondViewControllerDelegate {
    
    
    var delegate: SecondViewControllerDelegate?
    
    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var backButton: UIButton!
    
    var enteredName: String = ""
    
    func changeLabelText(name: String) {
        enteredName = name
    }

    @IBAction func backButtonPressed(_ sender: UIButton) {
        changeLabelText(name: nameTextField.text ?? "")
        delegate?.changeLabelText(name: nameTextField.text ?? "")
        print("das ist der name \(enteredName)")
        dismiss(animated: true)
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

您不会在backButtonPressed中两次调用任何委托方法。 您正在调用两个完全不同changeLabelText方法。 一个在SecondViewController中,另一个在委托中。

changeLabelText中调用SecondViewController是完全没有必要的。 其实SecondViewController中的enteredName属性是没有必要的。 此外, SecondViewController不应实现自己的委托。

您只需要在delegate上调用changeLabelText 您只需要在FirstViewController中更新changeLabelText的实现,以使用新值更新标签的文本。

func changeLabelText(name: String) {
    nameLabel.text = name
}

不要在FirstViewController中引用secondVC属性。 事实上,完全删除该属性。 它不是必需的,它引用的SecondViewController实例与您通过 segue 实际呈现的实例完全不同。

我还建议将委托方法从changeLabelText重命名为更通用的名称,例如enteredText 任何其他视图SecondViewController都可以使用 SecondViewController 来获取一些文本。 它不特定于更改 label。

这是带有建议更改的两个视图控制器:

class FirstViewController: UIViewController, SecondViewControllerDelegate {
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var button: UIButton!
    
    func enteredText(name: String) {
        nameLabel.text = name
    }
    
    @IBAction func buttonPressed(_ sender: UIButton) {
        performSegue(withIdentifier: "goToSecondVC", sender: self)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let destinationVC = segue.destination as? SecondViewController
        destinationVC?.delegate = self
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
protocol SecondViewControllerDelegate {
    func enteredText(name: String)
}

class SecondViewController: UIViewController {
    var delegate: SecondViewControllerDelegate?
    
    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var backButton: UIButton!
    
    @IBAction func backButtonPressed(_ sender: UIButton) {
        let name = nameTextField.text ?? ""
        delegate?.changeLabelText(name: name)
        print("das ist der name \(name)")
        dismiss(animated: true)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM