输入掩码限制数据输入,并允许您引导用户输入正确的值。
查看我们的wiki获取快速入门和更多阅读。
⚙️ 功能
- 将格式应用于文本字段,请见例子
- 过滤掉非必要符号(例如,从“+1 (999) 012-34-56”中提取“0123456”)
- 对于国际电话号码
- 猜测国家代码从输入的数字
- 应用相应的值限制(例如,一个
🇺🇸 美国电话将具有类似“+1 201 456-7890”的格式)
- 应用数字/货币格式
- SwiftUI支持
- macOS支持
💳 例子
- 电话号码:
+1 ([000]) [000] [00] [00]
- 日期:
[00]{.}[00]{.}[9900]
- 序列号:
[AA]-[00000099]
- IPv4:
[099]{.}[099]{.}[099]{.}[099]
- Visa/MasterCard卡号:
[0000] [0000] [0000] [0000]
- 英国IBAN:
GB[00] [____] [0000] [0000] [0000] [00]
🛠️ 安装
Swift包管理器
dependencies: [
.Package(url: "https://github.com/RedMadRobot/input-mask-ios", majorVersion: 7)
]
CocoaPods
pod 'InputMask'
手册
git clone
此仓库;- 将
InputMask.xcodeproj
添加到您的项目/工作区; - 转到您的目标设置,在
嵌入式二进制文件
部分下添加InputMask.framework
; - 对于
ObjC
项目- (~Xcode 8.x) 确保已启用
构建选项
中的嵌入式内容包含 Swift 代码
; - 导入桥接头。
- (~Xcode 8.x) 确保已启用
📢 通信、问题 & 问题
在将我们的库集成到项目中之前,请仔细查看我们的 已知问题 部分。
有关您的错误报告和功能请求,请通过 GitHub 创建新问题。
如果您有任何问题,请在 已关闭问题 中搜索,或在具有 input-mask
标签的 StackOverflow 上提出问题。
❗已知问题
UITextFieldTextDidChange
通知和 target-action editingChanged
事件
带有分配了 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事件和通知。
Carthage 与 IBDesignables、IBInspectables、视图及其的外观
Interface Builder 在支持以动态框架形式导入的模块方面存在困难。例如,被标注为 IBDesignable 的自定义视图(包含 IBInspectable 和 IBOutlet 字段)在从拖放 *.framework 导入时不会得到正确识别。
如果您正在将我们的库用作 Carthage 构建的动态框架,请注意您将无法轻松地将您的 MaskedTextFieldDelegate
对象及其监听器从项目中的 storyboards 中链接。尽管如此,虽然有一些建议在 相应的讨论中描述。
此外,请考虑向苹果提交一份类似这一份的报告。
剪切动作不会将文本放入剪贴板
当你剪切文本时,字符被删除,但是你不能将它们粘贴到任何地方,因为它们实际上不在你的剪贴板上。
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
属性。
MaskedTextInputListener
您可能会想知道为什么我们有两个不同的UITextFieldDelegate
和UITextViewDelegate
实现,答案是简单的:在iOS 11之前,UITextField
和UITextView
在某些关键情况下有不同的行为,这使得实现通用逻辑变得困难。
两个都有相同的bug,即UITextInput.beginningOfDocument
属性,这使得使用通用UITextInput
协议中UITextField
和UITextView
共有的部分变得不可能。
从iOS 11开始,大多数问题都得到了修复(除了一个UITextView
的边缘情况)。如果您的项目不支持低于11的版本,请考虑使用现代的MaskedTextInputListener
。
🙏 特别感谢
这些人非常出色
- Михаил while366 Задко
- Сергей СергейЧiP Germa-novich
- Луиз LuizZak Fer-nando
- Иван vani Вавилов
- Diego diegotl Trevisan
- Martin martintreurnicht Treurnicht
- Alexander CFIFok Kurilovich
♻️ 许可
本库在MIT 协议下分发。