【问题标题】:in Xcode, how does the delegating object know WHICH method on the delegate object to call?在 Xcode 中,委托对象如何知道要调用委托对象上的哪个方法?
【发布时间】:2017-04-21 15:34:12
【问题描述】:

例如,我有一个符合 UITextFieldDelegate 协议并从该协议继承方法的视图控制器..

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
                   replacementString string: String) -> Bool {
        // do some stuff...
        return true
    }

在 main.storyboard 文件中,我将文本字段控制拖动到此视图控制器,然后单击“委托”以让项目知道我的视图控制器现在是此文本字段的委托。

现在...我知道这个视图控制器现在在我的 UITextField 中称为“delegate”的属性下被引用,但是在我的视图控制器中,我的文本字段中有多个方法和属性。

文本字段是如何知道作为 textField(_:shouldChangeCharactersIn:replacementString) 函数的第一个参数传入的?与任何其他随机的、不相关的功能相反?

谢谢

奖金相关问题 在我的视图控制器(UITextField 的委托)中,有一个@IBAction 目标函数,其源是相同的文本字段输入对象。现在...我在该 IBAction 函数中具有基本上将输入值的输入 UPON 编辑的内容打印到屏幕上的功能。

但是,通过这个新的委托函数,我已经实现了一些功能,如果有两个相同的字符,则不会更改输入的值。当我运行我的应用程序时,我可以看到因为委托功能正在工作,当两个相同的数字出现在文本字段中时,文本字段中的值不会更新,因此甚至不会调用 @IBAction 函数(或者至少,控制台不会打印任何内容)。

在我看来,这表明委托函数优先于 @IBAction 函数。

只需根据观察结果寻找正确或错误的答案。谢谢!

【问题讨论】:

  • 您的文本字段将调用它必须调用的委托方法(因此可以是所有方法)。每种方法都有不同的目的。如果你只需要使用textField(_:shouldChangeCharactersIn:replacementString),那么你可以只实现这个委托方法。
  • 如果你想开始实现 Apple 的东西(iOS、macOS、tvOS 等),你必须了解更多关于 delegation 的知识,因为它是这些技术中使用的基本模式跨度>

标签: ios swift xcode delegates


【解决方案1】:

UITextField 内部的代码相当于:

self.delegate?.textfield(self, shouldChangeCharactersIn: rangeThatChanged, replacementString: stringThatChanged)

因此,文本字段代码调用其委托上的特定函数,传递所需的参数,包括对其自身的引用。这与在对象引用上调用任何函数没有什么不同。

关于您的“额外问题”,委托函数的名称是shouldChangeCharactersIn。此函数通过返回 true 或 false 来指示更改是否发生。如果它返回 false,则丢弃更改。如果没有变化,则不会调用 change 操作。

【讨论】:

  • 优秀的答案谢谢。不过,还有一个后续问题——当我们可以只使用@IBActions 时,为什么要使用将对象设置为另一个对象的委托的过程?例如,我在 IB 中看到我可以选择从文本字段到视图控制器设置一个名为“编辑确实开始”的 IBAction。然后我可以创建一个自定义函数来在调用它时执行 xyz。但是还有一个委托方法叫做“textFieldDidBeginEditing”......这两个不会做同样的事情吗?唯一的区别是委托方法是由 Apple 编写的并且具有预设功能?
  • 所有@IBAction 函数具有相同的签名。本质上functionName(sender: UIView)->Void IBAction 不能接受任何其他参数并且不返回值。您将不得不问 Apple,为什么 UITextField 的委托和操作之间存在重叠功能;我个人怀疑设置单个 delegate 属性比添加多个动作处理程序更简单(并且仍然必须为不能作为动作处理程序的事物设置委托)
  • 谢谢,我认为这回答了这个问题。因此,使用委托而不是 IBAction 可能有两个原因:(1)委托可以执行的某些方法不是“动作”,它们更像是请求信息的方法。就像阻止输入接受任何字符的那个一样,这与其说是一种动作,不如说是对值的测试。 (2) 当你开始添加多个动作处理程序时,使用 IBActions 可能会变得很繁重
  • 是的,你可能想要传递更多的值;考虑didSelectRowAtIndexPath - 它有一个 void 返回,但需要传递不同于 IBAction 签名可以接受的参数
【解决方案2】:

此方法的documentation 声明:

每当用户操作导致其文本发生更改时,文本字段都会调用此方法。

因此,当用户操作导致 UITextField 的文本发生更改时,UITextField 代码会检查 UITextField 对象是否具有委托,如果有,则该委托对象是否实现 textField(_:shouldChangeCharactersIn: replacementString:)。如果是,则 UITextField 调用该方法,将 UITextField 对象作为第一个参数传递。

【讨论】:

    猜你喜欢
    • 2018-11-11
    • 2011-01-19
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多