为啥在 shouldChangeCharactersIn 中返回 false 会覆盖 UITextField 中的旧文本?

Posted

技术标签:

【中文标题】为啥在 shouldChangeCharactersIn 中返回 false 会覆盖 UITextField 中的旧文本?【英文标题】:Why does returning false in shouldChangeCharactersIn override old text in UITextField?为什么在 shouldChangeCharactersIn 中返回 false 会覆盖 UITextField 中的旧文本? 【发布时间】:2020-04-04 17:17:17 【问题描述】:

问题代码

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 
    return false

TextField 创建

@discardableResult fileprivate func otpTextField() -> BJOTPTextField 

    let textField = BJOTPTextField()
    textField.text = "1"
    textField.delegate = self
    textField.textColor = .black
    textField.textAlignment = .center
    textField.isSecureTextEntry = true
    textField.keyboardType = .numberPad

    return textField

问题

我的视图控制器中有一个UITextField 子类,它在初始化时具有文本(“1”)。我将大文本复制粘贴到文本字段上。在shouldChangeCharactersIn 方法中,即使我显式返回false,文本字段中的当前文本(“1”)也会被删除,变为空,为什么

shouldChangeCharactersIn 文档

如果指定的文本范围应该被替换,则返回 true; 否则为 false 以保留旧文本。

为什么我的旧文本没有得到维护?一个重要的观察结果是文本字段覆盖发生在调用 shouldChangeCharactersIn 之前。很奇怪。


PS:文本字段的文本不会在shouldChangeCharactersIn 方法之外的任何地方更改/分配。

【问题讨论】:

【参考方案1】:

我知道为什么会这样。原因是文本字段是 SecureTextEntry 之一。

ios 中密码文本字段的默认行为是,当您已经在(密码)文本字段中输入了某些内容时,如果它再次成为第一响应者(通过早先退出其第一响应者状态),并且您粘贴或开始输入一些东西,现有的内容将被清除。假设之前的输入不正确,这恰好允许用户输入正确的密码。

这提供了良好的用户体验,但这种覆盖/清空不会在 shouldChangeCharactersIn 委托方法中的任何地方反映/广播。实际上,只有在文本覆盖发生后才会调用委托方法。

没有问题,如果它不是安全的文本字段,一切都会按预期正常工作。

【讨论】:

以上是关于为啥在 shouldChangeCharactersIn 中返回 false 会覆盖 UITextField 中的旧文本?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 5 - 用 X 屏蔽文本字段文本

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥在参数周围使用 /*、*/ 以及为啥在提取数组长度时使用 >>>? [复制]

为啥 CoreGui Roblox 锁定在 DataModel 中,为啥受信任的用户不能使用 CoreScripts?

为啥 + 仅在客户端是 NaN?为啥不在 Node.js 中?

在执行语义分割任务时我应该减去图像均值吗?为啥或者为啥不?