replacingCharacters 如何在委托中工作?

How does replacingCharacters work in a delegate?

我是 Swift 的新手,正在学习委托:

class ZipCodeTextFieldDelegate: NSObject, UITextFieldDelegate {

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

        var newText = textField.text! as NSString
        newText = newText.replacingCharacters(in: range, with: string) as NSString // this line

        return newText.length <= 5
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()

        return true;
    }
}

这基本上是一个将字符数限制在 5 个以内的委托。但是,我不太确定这个方法 replacingCharacters 在这个函数中扮演什么角色。苹果文档显示它

Returns a new string in which the characters in a specified range of the receiver are replaced by a given string.

这看起来很简单。它用您选择的替换替换了一些字符范围。我可以看到 textField 有一个名为 rangereplacementString 的参数,但是提供的范围是什么,它们被什么替换了?

使用委托的主要 ViewController 不提供其中任何一个。它只是简单地实例化委托并将其应用于相关的 textField

    let zipCodeDelegate = ZipCodeTextFieldDelegate()

    // MARK: Outlets

    @IBOutlet weak var textField: UITextField!


    // MARK: Life Cycle

    override func viewDidLoad() {
        super.viewDidLoad()

        self.textField.delegate = self.zipCodeDelegate

    }

首先,你应该明白shouldChangeCharactersIn的目的。每当用户试图以某种方式更改文本字段的文本时,文本字段都会询问其代表是否“应该更改字符”,即是否应该允许用户进行他们正在尝试进行的更改。

请注意,用户可以通过多种方式更改文本字段的文本,而不仅仅是“输入单个字符”。以下是可能的方法列表(您可能会想到其他方法):

  1. 输入单个字符,或粘贴一些文本
  2. 删除单个字符
  3. 选择一个字符范围,然后将其删除
  4. 选择一系列字符,然后输入单个字符,或粘贴一些文本。这将用单个字符或粘贴的文本替换所选范围

请注意,所有这些方式只是方式 4 的特例。在所有这些方式中,您只是用一些新文本替换文本字段文本中的范围。让我改写前三种方式:

  1. 用单个字符或一些粘贴的文本替换某个位置的 zero-length 范围
  2. 用空字符串替换 one-length 文本字段范围
  3. 用空字符串替换文本字段的某些范围

当用户尝试以任何方式更改文本字段的文本时,文本字段将进行类似如下的调用:

delegate?.textField(self, shouldChangeCharactersIn: someRange, replacementString: someString)

你现在应该明白参数someRangesomeString的作用了。无论用户如何更改文本,它总是可以建模为“用其他文本(someString)替换一段文本(someRange)”。

那么

newText.replacingCharacters(in: range, with: string)

做吗?

它只是做了前面提到的替换。回想一下,这个委托方法是询问您的文本字段,“是否允许这种更改(建模为范围和替换字符串)?”为了确定这一点,您首先尝试 进行更改 。如果更改后,文本字段的文本长度最多为5,则允许。

尝试进行更改

当然,您在进行此更改时并没有更改文本字段的文本,这就是为什么将其分配给名为 newText.

的变量的原因