[英]Why do I have to call my protocol functions two times to make it work?
我目前正在构建一个简单的应用程序来学习协议 - 委托功能。 然而,我的代码不起作用,即使我按照我在第一个练习应用程序中所做的方式进行了编辑。 在FirstViewController
中有一个UILabel
和一个UIButton
。 当用户点击UIButton
时,一个 segue 将他们带到SecondViewController
,他们应该在其中将他们的名字输入到UITextField
中。 之后,他们可以在UIButton
中按SecondViewController
,输入的名称应该显示在FirstViewController
的UILabel
中。
我不明白为什么我必须在@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.