输入掩码可以限制数据输入,并引导用户输入正确的值。
请查看我们的 wiki,以便快速入门和进一步阅读。
+1 (999) 012-34-56
中提取 0123456
)+1 201 456-7890
)+1 ([000]) [000] [00] [00]
[00]{.}[00]{.}[9900]
[AA]-[00000099]
[099]{.}[099]{.}[099]{.}[099]
[0000] [0000] [0000] [0000]
GB[00] [____] [0000] [0000] [0000] [00]
dependencies: [
.Package(url: "https://github.com/RedMadRobot/input-mask-ios", majorVersion: 7)
]
pod 'InputMask'
git clone
这个仓库;InputMask.xcodeproj
添加到您的项目/工作区;Embedded Binaries
部分下添加 InputMask.framework
ObjC
项目Build Options
启用了 Embedded Content Contains Swift Code
;在将我们的库集成到您的项目中之前,请仔细查看我们的已知问题部分。
对于您的错误报告和功能请求,请通过 GitHub 提交新的 issue。
如果您有任何问题,请搜索已关闭的 issues 或在 StackOverflow 上使用 input-mask
标签提问。
已分配 MaskedTextFieldDelegate
对象的 UITextField
不会发出 UITextFieldTextDidChange
通知和 editingChanged
控制事件。发生这种情况的原因是 textField(_:shouldChangeCharactersIn:replacementString:)
方法的实现始终返回 false
。
如果您确实需要捕获编辑事件,请考虑使用以下解决方法
class NotifyingMaskedTextFieldDelegate: MaskedTextFieldDelegate {
weak var editingListener: NotifyingMaskedTextFieldDelegateListener?
override func textField(
_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String
) -> Bool {
defer {
self.editingListener?.onEditingChanged(inTextField: textField)
}
return super.textField(textField, shouldChangeCharactersIn: range, replacementString: string)
}
}
protocol NotifyingMaskedTextFieldDelegateListener: class {
func onEditingChanged(inTextField: UITextField)
}
请尽可能避免手动发送 SDK 事件和通知。
Interface Builder 难以支持以动态框架形式导入的模块。例如,注释为 IBDesignable 的自定义视图,其中包含 IBInspectable 和 IBOutlet 字段,无法从拖放的 *.framework 中正确识别。
如果您正在使用我们的库作为 Carthage 构建的动态框架,请注意您将无法轻松地从项目的故事板中连接您的 MaskedTextFieldDelegate
对象及其侦听器。相应的讨论中描述了一些解决方法。
此外,请考虑向 Apple 提交雷达,例如这个。
当您剪切文本时,字符会被删除,但您无法将其粘贴到其他地方,因为它们实际上不在您的剪贴板中。
iOS 将 UIMenuController
的剪切操作硬连接到 UITextFieldDelegate
的 textField(_:shouldChangeCharactersIn:replacementString:)
返回值。这意味着“剪切”行为实际上取决于编辑文本的能力。
坏消息是,我们的库在 textField(_:shouldChangeCharactersIn:replacementString:)
中返回 false
,并且严重依赖于这个 false
。这将需要我们重写大量的逻辑才能改变这种设计,并且无法保证我们能够做到。
从本质上讲,在 UITextFieldDelegate
端没有明确的方法来区分“剪切选择”和“删除选择”操作。但是,您可以考虑使用一种解决方法,这将需要您子类化 UITextField
并覆盖其 cut(sender:)
方法,如下所示
class UITextFieldMonkeyPatch: UITextField {
override func cut(_ sender: Any?) {
copy(sender)
super.cut(sender)
}
}
从我们的库的角度来看,这看起来像是一种高度侵入性的解决方案。因此,从长远来看,我们将研究一种“昂贵”的方法来使该行为与 iOS SDK 逻辑匹配。然而,这里的“长远”可能意味着几个月。
在从剪贴板粘贴新文本后不久,每个 UITextInput
都会从系统收到其 selectedTextRange
属性的新值。这个新的范围与格式化的文本和计算的光标位置大多数时候不一致,但它会在调用 set caretPosition
之后立即被分配。
为了确保设置了正确的光标位置,如果光标移动设置为非原子性的,则可以异步分配(可能在极短的延迟后);请参阅 MaskedTextFieldDelegate.atomicCursorMovement
属性。
如果您想知道为什么我们有两个单独的 UITextFieldDelegate
和 UITextViewDelegate
实现,答案很简单:在 **iOS 11** 之前,UITextField
和 UITextView
在一些关键情况下具有不同的行为,这使得难以实现通用逻辑。
两者都存在与 UITextInput.beginningOfDocument
属性相关的相同错误,这使得无法使用 UITextField
和 UITextView
共有的通用 UITextInput
协议。
自 **iOS 11** 以来,大多数事情都得到了修复(除了 UITextView
边缘情况)。如果您的项目不打算支持低于 11 的任何版本,请考虑使用现代的 MaskedTextInputListener
。
这些人太棒了
该库以 MIT LICENSE 许可证分发。