Мое решение работает так:
Реализация в вашем текстовом поле делегатов:
func textFieldDidBeginEditing(_ textField: UITextField) {
// When you start editing check if there is nothing, in that case add the entire mask
if let text = textField.text, text == "" || text == "DD/MM/YYYY" {
textField.text = "DD/MM/YYYY"
textField.textColor = .lightGray
textField.setCursor(position: text.count)
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard var number = textField.text else {
return true
}
// If user try to delete, remove the char manually
if string == "" {
number.remove(at: number.index(number.startIndex, offsetBy: range.location))
}
// Remove all mask characters
number = number.replacingOccurrences(of: "/", with: "")
number = number.replacingOccurrences(of: "D", with: "")
number = number.replacingOccurrences(of: "M", with: "")
number = number.replacingOccurrences(of: "Y", with: "")
// Set the position of the cursor
var cursorPosition = number.count+1
if string == "" {
//if it's delete, just take the position given by the delegate
cursorPosition = range.location
} else {
// If not, take into account the slash
if cursorPosition > 2 && cursorPosition < 5 {
cursorPosition += 1
} else if cursorPosition > 4 {
cursorPosition += 2
}
}
// Stop editing if we have rich the max numbers
if number.count == 8 { return false }
// Readd all mask char
number += string
while number.count < 8 {
if number.count < 2 {
number += "D"
} else if number.count < 4 {
number += "M"
} else {
number += "Y"
}
}
number.insert("/", at: number.index(number.startIndex, offsetBy: 4))
number.insert("/", at: number.index(number.startIndex, offsetBy: 2))
// Some styling
let enteredTextAttribute = [NSForegroundColorAttributeName: UIColor.black, NSFontAttributeName: UIFont.systemFont(ofSize: 15)]
let maskTextAttribute = [NSForegroundColorAttributeName: UIColor.lightGray, NSFontAttributeName: UIFont.systemFont(ofSize: 15)]
let partOne = NSMutableAttributedString(string: String(number.prefix(cursorPosition)), attributes: enteredTextAttribute)
let partTwo = NSMutableAttributedString(string: String(number.suffix(number.count-cursorPosition)), attributes: maskTextAttribute)
let combination = NSMutableAttributedString()
combination.append(partOne)
combination.append(partTwo)
textField.attributedText = combination
textField.setCursor(position: cursorPosition)
return false
}
func textFieldDidEndEditing(_ textField: UITextField) {
if let text = textField.text, text != "" && text != "DD/MM/YYYY" {
// Do something with your value
} else {
textField.text = ""
}
}
И этот маленький помощник какрасширение:
extension UITextField {
func setCursor(position: Int) {
let position = self.position(from: beginningOfDocument, offset: position)!
selectedTextRange = textRange(from: position, to: position)
}
}
PS: в этой реализации все еще есть ошибка, когда вы пытаетесь переместить курсор во время редактирования