Максимальная длина UITextField
когда я пробовал, как установить максимальное количество символов, которые могут быть введены в UITextField с помощью swift? Я увидел, что если я использую все 10 символов, я не могу стереть персонажа.
единственное, что я могу сделать, это отменить операцию (удалить все символы вместе).
кто-нибудь знает, как не блокировать клавиатуру (так что я не могу добавить другие буквы/символы/цифры, но я могу использовать backspace)?
14 ответов:
для Swift 3, попробуйте следующую реализацию
textField(_:shouldChangeCharactersIn:replacementString:)
, что является частьюUITextFieldDelegate
протокол:func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let text = textField.text else { return true } let newLength = text.characters.count + string.characters.count - range.length return newLength <= 10 // Bool }
в соответствии с вашими потребностями, однако, вы можете предпочесть эту реализацию (см. строки в Swift 2 для более подробной информации):
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let text = textField.text else { return true } let newLength = text.utf16.count + string.utf16.count - range.length return newLength <= 10 // Bool }
приведенный ниже код показывает, как реализовать его в
UIViewController
:import UIKit class ViewController: UIViewController, UITextFieldDelegate { @IBOutlet weak var textField: UITextField! // Link this to a UITextField in your storyboard let limitLength = 10 override func viewDidLoad() { super.viewDidLoad() textField.delegate = self } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let text = textField.text else { return true } let newLength = text.characters.count + string.characters.count - range.length return newLength <= limitLength } }
Я делаю это так:
func checkMaxLength(textField: UITextField!, maxLength: Int) { if (countElements(textField.text!) > maxLength) { textField.deleteBackward() } }
код работает для меня. Но я работаю с раскадровкой. В раскадровке я добавляю действие для текстового поля в контроллере вида на редактирование изменен.
обновление для Swift 4
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let text = textField.text else { return true } let newLength = text.count + string.count - range.length return newLength <= 10 }
добавить более подробную информацию от @Martin answer
// linked your button here @IBAction func mobileTFChanged(sender: AnyObject) { checkMaxLength(sender as! UITextField, maxLength: 10) } // linked your button here @IBAction func citizenTFChanged(sender: AnyObject) { checkMaxLength(sender as! UITextField, maxLength: 13) } func checkMaxLength(textField: UITextField!, maxLength: Int) { // swift 1.0 //if (count(textField.text!) > maxLength) { // textField.deleteBackward() //} // swift 2.0 if (textField.text!.characters.count > maxLength) { textField.deleteBackward() } }
func checkMaxLength(textField: UITextField!, maxLength: Int) { if (textField.text!.characters.count > maxLength) { textField.deleteBackward() } }
небольшое изменение для IOS 9
Swift 3
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let nsString = NSString(string: textField.text!) let newText = nsString.replacingCharacters(in: range, with: string) return newText.characters.count <= limitCount }
В Swift 4
10 символов ограничение для текстового поля и позволяют удалить (backspace)
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField == userNameFTF{ let char = string.cString(using: String.Encoding.utf8) let isBackSpace = strcmp(char, "\b") if isBackSpace == -92 { return true } return textField.text!.count <= 9 } return true }
Я разместил решение с помощью
IBInspectable
, поэтому вы можете изменить максимальное значение длины как в interface builder, так и программно. посмотреть здесь
Если вы хотите переписать последнюю букву:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if range.location > 9 { textField.text?.removeLast() } return true }
остерегайтесь ошибки отмены для UITextField, упомянутой в этом сообщении:установить максимальное количество символов в поле UITextField
вот как вы это исправить в swift
if(range.length + range.location > count(textField.text)) { return false; }
Here is my version of code. Hope it helps! func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let invalidCharacters = NSCharacterSet(charactersInString: "0123456789").invertedSet if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex)) { return false } if (count(textField.text) > 10 && range.length == 0) { self.view.makeToast(message: "Amount entry is limited to ten digits", duration: 0.5, position: HRToastPositionCenter) return false } else { } return true }
Я использую это расширение протокола / в одном из моих приложений, и это немного более читабельным. Мне нравится, как он распознает обратные пространства и явно говорит вам, когда символ является обратным пространством.
некоторые вещи, чтобы рассмотреть:
1.Независимо от того, что реализует это расширение протокола, необходимо указать ограничение символов. обычно это будет ваш ViewController, но вы можете реализовать ограничение символов как вычисляемое свойство и вернуть что-то другое, например символов на одной из ваших моделей.
2. Вам нужно будет вызвать этот метод внутри вашего текстового поля shouldChangeCharactersInRange делегат метод. в противном случае вы не сможете блокировать ввод текста, возвращая false и т. д.
3. Вероятно, вы захотите разрешить символы backspace. вот почему я добавил дополнительную функцию для обнаружения backspaces. Ваш метод shouldChangeCharacters может проверить это и возвращает true, чтобы вы всегда позвольте backspaces.
protocol TextEntryCharacterLimited{ var characterLimit:Int { get } } extension TextEntryCharacterLimited{ func charactersInTextField(textField:UITextField, willNotExceedCharacterLimitWithReplacementString string:String, range:NSRange) -> Bool{ let startingLength = textField.text?.characters.count ?? 0 let lengthToAdd = string.characters.count let lengthToReplace = range.length let newLength = startingLength + lengthToAdd - lengthToReplace return newLength <= characterLimit } func stringIsBackspaceWith(string:String, inRange range:NSRange) -> Bool{ if range.length == 1 && string.characters.count == 0 { return true } return false } }
Если кто-то из вас заинтересован, у меня есть репозиторий Github, где я взял некоторые из этих ограничений поведения символов и поместил в рамки iOS. Есть протокол, который вы можете реализовать, чтобы получить Твиттер-подобный дисплей ограничения символов, который показывает вам, как далеко Вы зашли выше предела символов.
поскольку делегаты являются отношением 1 к 1, и я могу использовать его в другом месте по другим причинам, мне нравится ограничивать длину текстового поля, добавляя этот код в свою настройку:
required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! setup() } required override init(frame: CGRect) { super.init(frame: frame) setup() } func setup() { // your setup... setMaxLength() } let maxLength = 10 private func setMaxLength() { addTarget(self, action: #selector(textfieldChanged(_:)), for: UIControlEvents.editingChanged) } @objc private func textfieldChanged(_ textField: UITextField) { guard let text = text else { return } let trimmed = text.characters.prefix(maxLength) self.text = String(trimmed) }
вы должны проверить, является ли существующая строка плюс вход больше 10.
func textField(textField: UITextField!,shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool { NSUInteger newLength = textField.text.length + string.length - range.length; return !(newLength > 10) }