我有一个关于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调用的情况下调用的函数!
想象一下(尽管这只是一个概念(:
- 有人将
UIButton
编码为键盘的return
按钮 - 在
touchUpInside
中,该按钮的事件调用如下:
if self.delegate?.textFieldShouldReturn?(self) ?? true {
// Insert new line or smt.
}
- 如果
delegate
不是nil
,并且textFieldShouldReturn
在您的代码中实现,则将调用您的代码。否则,将执行默认实现
注意这只是一个概念,不是UITextField
类的真正实现