Включить редактирование TextField только с конца текста внутри него

Я создаю TextField для номера телефона. Но у меня есть проблема: мне нужно запретить пользователям редактировать его из любого места, а не из конца строки.

Я попытался сбросить курсор, используя «Touch up Inside», но он кажется отключенным для TextField.

Есть ли способ ограничить возможные позиции каретки?

Проблема в том, что это портит мой код, который форматирует номер телефона. Если у вас есть другие хорошие способы отформатировать его без этой проблемы (мне нужно, чтобы строка выглядела именно так: +7 (123) 456-78-90, а не иначе), буду признателен за вашу помощь.

private static var prev_phone: String = ""
@IBAction func phoneFieldTextChanged(_ sender: Any){
    if let phone = phone_field.text{
        if (phone.count <= 4){
            phone_field.text = "+7 ("
        }
        else{
            if phone.count > RegistrationViewController.prev_phone.count{
                if (phone.count == 7){
                    phone_field.text! += ") "
                }
                if (phone.count == 12){
                    phone_field.text! += "-"
                }
                if (phone.count == 15){
                    phone_field.text! += "-"
                }
                if (phone.count > 18){
                    phone_field.text = String(phone.prefix(18))
                }
            }
            if phone.count < RegistrationViewController.prev_phone.count{
                if (phone.count == 8){
                    phone_field.text! = String(phone.prefix(6))
                }
                if (phone.count == 12){
                    phone_field.text! = String(phone.prefix(11))
                }
                if (phone.count == 15){
                    phone_field.text! = String(phone.prefix(14))
                }
                if (phone.count > 18){
                    phone_field.text = String(phone.prefix(18))
                }
            }
        }
    }
    else{
        phone_field.text = "+7 ("
    }
    RegistrationViewController.prev_phone = phone_field.text!
}
Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
0
0
229
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В этом случае зачем использовать UITextField? Например, вы можете создать собственную клавиатуру, используя только цифру и кнопку удаления. Пользователь может только ввести число или удалить его. вы можете добавить введенную цифру в форматированную строку.

Ответ принят как подходящий

Назначьте этот класс своему текстовому полю, чтобы пользователи не могли редактировать его из любого места.

class RestrictionTextField: UITextField {

    override func closestPosition(to point: CGPoint) -> UITextPosition? {
        let beginning = self.beginningOfDocument
        let end = self.position(from: beginning, offset: self.text?.count ?? 0)
        return end
    }
    
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(UIResponderStandardEditActions.copy(_:)) || action == #selector(UIResponderStandardEditActions.select(_:)) || action == #selector(UIResponderStandardEditActions.cut(_:)) || action == #selector(UIResponderStandardEditActions.paste(_:)) || action == #selector(UIResponderStandardEditActions.selectAll(_:)){
            return false
        }
        else {
            return super.canPerformAction(action, withSender: sender)
        }
    }
}

Для вашего текстового поля вы можете использовать это простое решение.

let kPhonePattern = "+# (###) ###-##-##"
let kPhonePatternReplaceChar: Character = "#"

extension String {
    var digits: String {
        return String(filter(("0"..."9").contains))
    }
    
    func applyPatternOnNumbers(pattern: String = kPhonePattern, replacmentCharacter: Character = kPhonePatternReplaceChar) -> String {
        var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
        for index in 0 ..< pattern.count {
            guard index < pureNumber.count else { return pureNumber }
            let stringIndex = String.Index(encodedOffset: index)
            let patternCharacter = pattern[stringIndex]
            guard patternCharacter != replacmentCharacter else { continue }
            pureNumber.insert(patternCharacter, at: stringIndex)
        }
        return pureNumber
    }
}

Использование:

@IBAction func phoneFieldTextChanged(_ sender: UITextField){
    sender.text = sender.text?.applyPatternOnNumbers()
}

Вау, оба решения действительно делают то, для чего они предназначены. Большое спасибо, что потратили время на такой тупой вопрос)

Stepan Kuznetsov 18.12.2020 17:46

Инициализатор строки не требуется. filterприменяется к строке, возвращает строку. var digits: String { filter(("0"..."9").contains) }. Кстати, почему вы добавили это свойство и не использовали его? var pureNumber = digits

Leo Dabus 18.12.2020 19:10

@LeoDabus Я добавил, если вам нужно получить цифру из текстового поля (с шаблоном), тогда это полезно. Он возвращает только цифры. И спасибо за поправку фильтра.

Raja Kishan 19.12.2020 10:32

Другие вопросы по теме