Swift Xcode中的协议和功能



我有一个关于Swift中的协议和函数的初学者问题。我已经跟随余的课程大约一个月了。

我正试图理解在下面的代码中,函数";textFieldShouldReturn"可以在不被调用的情况下激活。

import UIKit
class WeatherViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var conditionImageView: UIImageView!
@IBOutlet weak var temperatureLabel: UILabel!
@IBOutlet weak var cityLabel: UILabel!

@IBOutlet weak var searchTextField: UITextField!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
searchTextField.delegate = self

}

@IBAction func searchPressed(_ sender: UIButton) {
print (searchTextField.text!)
searchTextField.endEditing(true)
}

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

我知道,因为WeatherViewController连接到协议UITextFieldDelegate,所以我能够访问函数,如func textFieldShouldReturn或func textFieldShouldEndEditing。但我很难想象幕后发生了什么,这使得当我运行程序时,即使我的代码没有明确调用它,函数也可以激活。

如果有人能像我5岁那样解释,我将不胜感激。

UITextFieldDelegate是一个协议。当您使用该协议继承了您的控制器时,这意味着现在所有函数(该协议的调用,在我们的例子中是TEXTFIELD(都可以在控制器中接收。

在viewDidLoad中,您已经告诉您的特定文本字段(在我们的例子中是"searchTextField"(,让您调用该控制器中的所有文本字段。

tl;dr的答案是,当您的视图加载时,WeatherViewController将自己设置为searchTextField的委托,而searchTextField正在调用您的函数。

你可能知道,你在应用程序的用户界面中看到的一切都是作为Swift对象实现的[*]。在searchTextField的情况下,对象是UITextField的实例。这个对象负责与屏幕上的搜索文本字段有关的一切。它绘制文本字段及其内容,并管理所有输入。因此,如果您在字段具有焦点时按下某个键,那么UITextField将接受输入、更新内容并告诉窗口系统需要重新绘制。在按下返回键的情况下,UITextField将有一些默认操作,我认为这是放弃焦点,让窗口系统移动到下一个字段。

委托是UITextField用来修改不同点的默认行为的对象。委托实现在UITextField生命周期中的各个点调用的函数集合。因此,意识到按下返回键时您可能不想要默认行为,UITextField

  • 检查是否有委托
  • 如果它确实有委托,则检查该委托是否具有函数textFieldShouldReturn
  • 如果委托确实具有该函数,则UITextField会调用它

在特定的限制范围内,您可以在委托函数中执行任何您喜欢的操作,然后UITextField检查返回值,看看它是否也应该执行默认操作。

我有几个关于术语的注释:

  • WeatherViewController未连接到协议。我们说它采用了协议或者它符合协议。该协议为采用它的类和结构设置约束。通常,协议中列出的方法必须在采用它的类别中实现。UITextFieldDelegate的情况并非如此-方法都标记为可选-但它确实设置了类必须是Objective-C类的约束。纯Swift类不存在可选方法。在您的情况下,UIViewController是一个Objective-C类,并且您从中继承,因此满足了约束
  • 我们不激活功能,我们调用它们。你的问题应该是";当我的函数在我的代码中没有被引用时,如何调用它">

很抱歉对语言有点挑剔,但我发现如果我采用正确的术语,这确实有助于我理清思路。

[*]Objective-C对象实际上是

该函数可以在不调用的情况下激活

这里的句子不对。正确的是:

在没有ME调用的情况下调用的函数!

想象一下(尽管这只是一个概念(:

  1. 有人将UIButton编码为键盘的return按钮
  2. touchUpInside中,该按钮的事件调用如下:

if self.delegate?.textFieldShouldReturn?(self) ?? true {
// Insert new line or smt.
}
  1. 如果delegate不是nil,并且textFieldShouldReturn在您的代码中实现,则将调用您的代码。否则,将执行默认实现

注意这只是一个概念,不是UITextField类的真正实现

最新更新