[英]Why do I have to call my protocol functions two times to make it work?
I'm currently building a simple app to learn the protocol - delegate functionality.我目前正在构建一个简单的应用程序来学习协议 - 委托功能。 However my code doesn't work, even after I edited the way I did in my first practice app where it worked.然而,我的代码不起作用,即使我按照我在第一个练习应用程序中所做的方式进行了编辑。 In the FirstViewController
there is a UILabel
and a UIButton
.在FirstViewController
中有一个UILabel
和一个UIButton
。 When the user taps on the UIButton
, a segue brings them to the SecondViewController
where they should enter their name into a UITextField
.当用户点击UIButton
时,一个 segue 将他们带到SecondViewController
,他们应该在其中将他们的名字输入到UITextField
中。 After that, they can press the UIButton
in the SecondViewController
and the entered Name should be displayed in the UILabel
in the FirstViewController
.之后,他们可以在UIButton
中按SecondViewController
,输入的名称应该显示在FirstViewController
的UILabel
中。
I can't figure out why I have to call the protocol function two times in the @IBAction backButtonPresses()
.我不明白为什么我必须在@IBAction backButtonPresses()
中调用协议 function 两次。 Also, I can't figure out how to handle the same protocol function in the FirstViewController
.另外,我无法弄清楚如何在 FirstViewController 中处理相同的协议FirstViewController
。
Here's the code for the FirstViewController.swift
file:这是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
}
}
And here's the code of the secondViewController
:这是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()
}
}
You do not call any delegate method twice in backButtonPressed
.您不会在backButtonPressed
中两次调用任何委托方法。 You are calling two completely different changeLabelText
methods.您正在调用两个完全不同changeLabelText
方法。 One is in SecondViewController
, the other is on the delegate.一个在SecondViewController
中,另一个在委托中。
The call to changeLabelText
in the SecondViewController
is quite unnecessary.在changeLabelText
中调用SecondViewController
是完全没有必要的。 In fact, the enteredName
property in SecondViewController
is unnecessary.其实SecondViewController
中的enteredName
属性是没有必要的。 Also, SecondViewController
should not be implementing its own delegate.此外, SecondViewController
不应实现自己的委托。
The call to changeLabelText
on delegate
is all you need.您只需要在delegate
上调用changeLabelText
。 You just need to update the implementation of changeLabelText
in FirstViewController
to update the label's text with the new value.您只需要在FirstViewController
中更新changeLabelText
的实现,以使用新值更新标签的文本。
func changeLabelText(name: String) {
nameLabel.text = name
}
Do not reference the secondVC
property in FirstViewController
.不要在FirstViewController
中引用secondVC
属性。 In fact, remove that property completely.事实上,完全删除该属性。 It's not needed and it's referencing a completely different instance of SecondViewController
than the one you actually present via segue.它不是必需的,它引用的SecondViewController
实例与您通过 segue 实际呈现的实例完全不同。
I also suggest renaming the delegate method from changeLabelText
to something more general such as enteredText
.我还建议将委托方法从changeLabelText
重命名为更通用的名称,例如enteredText
。 SecondViewController
can be used by any other view controller to obtain some text.任何其他视图SecondViewController
都可以使用 SecondViewController 来获取一些文本。 It's not specific to changing a label.它不特定于更改 label。
Here's your two view controllers with suggested changes:这是带有建议更改的两个视图控制器:
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.