[英]Swift. Format input in textField
I created textField and want to format text in it like 43/35.我创建了 textField 并希望像 43/35 一样格式化文本。 Number / number - for credit card month and year. Number / number - 信用卡月份和年份。
Can I use number fomatter for it or how can I do it more easily?我可以使用数字格式化程序吗,或者我怎样才能更轻松地做到这一点? The issue here that I need to replace 3rd character if I add new character and remove it if I remove 2nd one.这里的问题是,如果添加新字符,则需要替换第三个字符,如果删除第二个字符,则需要将其删除。
I do not want use any 3rd party library, I need native implementation我不想使用任何 3rd 方库,我需要本机实现
This is my current solution.这是我目前的解决方案。 Basically you need to:基本上你需要:
1) Implement the delegate
of your textfield
somewhere (in my code below I implemented on the ViewController) 1)在某处实现你的textfield
的delegate
(在我下面的代码中,我在 ViewController 上实现了)
2) Implement textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
. 2) 实现textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
。
To apply the mask, I created some extensions for String and Characters, as you can see at the end of the following code:为了应用掩码,我为字符串和字符创建了一些扩展,如以下代码末尾所示:
class ViewController: UIViewController {
@IBOutlet weak var textfield: UITextField!
let mask = "##/##"
override func viewDidLoad() {
super.viewDidLoad()
textfield.delegate = self
}
}
extension ViewController: UITextFieldDelegate {
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
guard let normalText = textField.text else { return false }
let beginning = textField.beginningOfDocument
// save cursor location
let cursorLocation = textField.positionFromPosition(beginning, offset: range.location + string.characters.count)
let newString = (normalText as NSString).stringByReplacingCharactersInRange(range, withString: string)
let newStringClean = newString.stringWithOnlyNumbers().withMask(mask)
guard newString != newStringClean else { return true }
textField.text = newStringClean
guard string != "" else { return false }
// fix cursor location after changing textfield.text
if let cL = cursorLocation {
let textRange = textField.textRangeFromPosition(cL, toPosition: cL)
textField.selectedTextRange = textRange
}
return false
}
}
extension String {
func stringWithOnlyNumbers() -> String {
return self.characters.reduce("") { (acc, c) -> String in
guard c.isDigit() else { return acc }
return "\(acc)\(c)"
}
}
func withMask(mask: String) -> String {
var resultString = String()
let chars = self.characters
let maskChars = mask.characters
var stringIndex = chars.startIndex
var maskIndex = mask.startIndex
while stringIndex < chars.endIndex && maskIndex < maskChars.endIndex {
if (maskChars[maskIndex] == "#") {
resultString.append(chars[stringIndex])
stringIndex = stringIndex.successor()
} else {
resultString.append(maskChars[maskIndex])
}
maskIndex = maskIndex.successor()
}
return resultString
}
}
extension Character {
func isDigit() -> Bool {
let s = String(self).unicodeScalars
let uni = s[s.startIndex]
let digits = NSCharacterSet.decimalDigitCharacterSet()
let isADigit = digits.longCharacterIsMember(uni.value)
return isADigit
}
}
Swift 4:斯威夫特 4:
extension CodeEnterViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let normalText = textField.text else { return false }
let beginning = textField.beginningOfDocument
// save cursor location
let cursorLocation = textField.position(from: beginning, offset: range.location + string.count)
let newString = (normalText as NSString).replacingCharacters(in: range, with: string)
let newStringClean = newString.stringWithOnlyNumbers().withMask(mask: mask)
guard newString != newStringClean else { return true }
textField.text = newStringClean
guard string != "" else { return false }
// fix cursor location after changing textfield.text
if let cL = cursorLocation {
let textRange = textField.textRange(from: cL, to: cL)
textField.selectedTextRange = textRange
}
return false
}
}
String字符串
extension String {
func stringWithOnlyNumbers() -> String {
return self.reduce("") { (acc, c) -> String in
guard c.isDigit() else { return acc }
return "\(acc)\(c)"
}
}
func withMask(mask: String) -> String {
var resultString = String()
let chars = self
let maskChars = mask
var stringIndex = chars.startIndex
var maskIndex = mask.startIndex
while stringIndex < chars.endIndex && maskIndex < maskChars.endIndex {
if (maskChars[maskIndex] == "#") {
resultString.append(chars[stringIndex])
stringIndex = chars.index(after: stringIndex)
} else {
resultString.append(maskChars[maskIndex])
}
maskIndex = chars.index(after: maskIndex)
}
return resultString
}
}
Character性格
extension Character {
func isDigit() -> Bool {
let s = String(self).unicodeScalars
let uni = s[s.startIndex]
let digits = NSCharacterSet.decimalDigits
let isADigit = digits.hasMember(inPlane: UInt8(uni.value))
return isADigit
} }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.