Установите максимальную длину символа UITextField в Swift
Я знаю, что есть другие темы, но я не могу понять, как его реализовать.
Я пытаюсь ограничить UITextField только 5 символами
Предпочтительно буквенно-цифровые и - и. и _
Я видел этот код
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool
{
let maxLength = 4
let currentString: NSString = textField.text
let newString: NSString =
currentString.stringByReplacingCharactersInRange(range, withString: string)
return newString.length <= maxLength
}
и
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let length = count(textField.text.utf16) + count(string.utf16) - range.length
return length <= 10
}
Я просто не знаю, как на самом деле реализовать его или какое "текстовое поле" следует поменять для моего пользовательского имени UITextField
Ответы
Ответ 1
-
Контроллер вашего представления должен соответствовать UITextFieldDelegate
, как показано ниже:
class MyViewController: UIViewController, UITextFieldDelegate {
}
-
Задайте делегат вашего текстового поля: myTextField.delegate = self
- Внедрить метод в вашем контроллере вида:
textField(_:shouldChangeCharactersInRange:replacementString:)
Все вместе:
class MyViewController: UIViewController,UITextFieldDelegate //set delegate to class
@IBOutlet var mytextField: UITextField // textfield variable
override func viewDidLoad() {
super.viewDidLoad()
mytextField.delegate = self //set delegate
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool
{
let maxLength = 4
let currentString: NSString = textField.text
let newString: NSString =
currentString.stringByReplacingCharactersInRange(range, withString: string)
return newString.length <= maxLength
}
Для Swift 4
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let maxLength = 1
let currentString: NSString = textField.text! as NSString
let newString: NSString =
currentString.replacingCharacters(in: range, with: string) as NSString
return newString.length <= maxLength
}
Разрешить ввод только определенного набора символов в заданное текстовое поле
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
var result = true
if mytextField == numberField {
if count(string) > 0 {
let disallowedCharacterSet = NSCharacterSet(charactersInString: "0123456789.-").invertedSet
let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
result = replacementStringIsLegal
}
}
return result
}
Как запрограммировать текстовое поле iOS, которое принимает только числовой ввод с максимальной длиной
Ответ 2
Декабрь 2017. Swift 4.
Позаботьтесь о том, чтобы большая часть кода примера, который вы увидите в Интернете об этой проблеме, очень устарела.
Вставьте следующее в любой файл Swift в вашем проекте. Вы можете назвать файл как угодно, например, "Handy.swift"
Это, наконец, решает одну из самых глупых проблем в iOS:
![enter image description here]()
Ваши текстовые поля теперь имеют .maxLength
.
Вполне допустимо установить это значение в раскадровке во время разработки или в коде во время работы приложения.
// simply have this in any Swift file, say, Handy.swift
import UIKit
private var __maxLengths = [UITextField: Int]()
extension UITextField {
@IBInspectable var maxLength: Int {
get {
guard let l = __maxLengths[self] else {
return 150 // (global default-limit. or just, Int.max)
}
return l
}
set {
__maxLengths[self] = newValue
addTarget(self, action: #selector(fix), for: .editingChanged)
}
}
func fix(textField: UITextField) {
let t = textField.text
textField.text = t?.prefix(maxLength)
}
}
Это так просто.
Сноска - в наши дни, чтобы безопасно обрезать String
по-быстрому, вы просто .prefix(n)
Еще более простая одноразовая версия...
Выше исправлены все текстовые поля в вашем проекте.
Если вы просто хотите, чтобы одно конкретное текстовое поле было просто ограничено, чтобы сказать "4", и это...
class PinCodeEntry: UITextField {
override func didMoveToSuperview() {
super.didMoveToSuperview()
addTarget(self, action: #selector(fixMe), for: .editingChanged)
}
@objc private func fixMe() { text = text?.prefix(4) }
}
Уф! Это все, что нужно.
(Кстати, вот похожий очень полезный совет, касающийся UIText View,
fooobar.com/questions/19279/...)
Ответ 3
Swift 4, просто используйте:
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return range.location < 10
}
Ответ 4
Точно так же Стивен Шматц сделал это, но использовал Swift 3.0:
//max Length
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool
{
let maxLength = 4
let currentString: NSString = textField.text! as NSString
let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
return newString.length <= maxLength
}
Ответ 5
Я думаю, что расширение более удобно для этого. Полный ответ здесь
private var maxLengths = [UITextField: Int]()
// 2
extension UITextField {
// 3
@IBInspectable var maxLength: Int {
get {
// 4
guard let length = maxLengths[self] else {
return Int.max
}
return length
}
set {
maxLengths[self] = newValue
// 5
addTarget(
self,
action: #selector(limitLength),
forControlEvents: UIControlEvents.EditingChanged
)
}
}
func limitLength(textField: UITextField) {
// 6
guard let prospectiveText = textField.text
where prospectiveText.characters.count > maxLength else {
return
}
let selection = selectedTextRange
// 7
text = prospectiveText.substringWithRange(
Range<String.Index>(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
)
selectedTextRange = selection
}
}
Ответ 6
Другие решения, опубликованные выше, производят цикл сохранения из-за карты текстового поля. Кроме того, свойство maxLength
должно иметь значение NULL, если оно не задано вместо искусственных конструкций Int.max
; и цель будет установлена несколько раз, если maxLength будет изменен.
Здесь обновленное решение для Swift4 со слабой картой для предотвращения утечек памяти и других исправлений
private var maxLengths = NSMapTable<UITextField, NSNumber>(keyOptions: NSPointerFunctions.Options.weakMemory, valueOptions: NSPointerFunctions.Options.strongMemory)
extension UITextField {
var maxLength: Int? {
get {
return maxLengths.object(forKey: self)?.intValue
}
set {
removeTarget(self, action: #selector(limitLength), for: .editingChanged)
if let newValue = newValue {
maxLengths.setObject(NSNumber(value: newValue), forKey: self)
addTarget(self, action: #selector(limitLength), for: .editingChanged)
} else {
maxLengths.removeObject(forKey: self)
}
}
}
@IBInspectable var maxLengthInspectable: Int {
get {
return maxLength ?? Int.max
}
set {
maxLength = newValue
}
}
@objc private func limitLength(_ textField: UITextField) {
guard let maxLength = maxLength, let prospectiveText = textField.text, prospectiveText.count > maxLength else {
return
}
let selection = selectedTextRange
text = String(prospectiveText[..<prospectiveText.index(from: maxLength)])
selectedTextRange = selection
}
}
Ответ 7
Моя версия Swift 4 shouldChangeCharactersIn
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
guard let preText = textField.text as NSString?,
preText.replacingCharacters(in: range, with: string).count <= MAX_TEXT_LENGTH else {
return false
}
return true
}
Ответ 8
У меня есть что добавить в ответ Аладина:
-
Контроллер вашего представления должен соответствовать UITextFieldDelegate
class MyViewController: UIViewController, UITextViewDelegate {
}
-
Установите делегат текстового поля:
Чтобы установить делегат, вы можете управлять перетаскиванием из текстового поля в контроллер вида в раскадровке. Я думаю, что это предпочтительнее установить его в коде
-
Внедрите метод в своем контроллере вида: textField(_:shouldChangeCharactersInRange:replacementString:)
Ответ 9
Я даю дополнительный ответ, основанный на @Frouo. Я думаю, что его ответ - самый красивый способ. Постарайтесь, чтобы это был общий контроль, который мы можем использовать повторно. И здесь нет проблемы с утечкой.
private var kAssociationKeyMaxLength: Int = 0
extension UITextField {
@IBInspectable var maxLength: Int {
get {
if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
return length
} else {
return Int.max
}
}
set {
objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
self.addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
}
}
//The method is used to cancel the check when use Chinese Pinyin input method.
//Becuase the alphabet also appears in the textfield when inputting, we should cancel the check.
func isInputMethod() -> Bool {
if let positionRange = self.markedTextRange {
if let _ = self.position(from: positionRange.start, offset: 0) {
return true
}
}
return false
}
func checkMaxLength(textField: UITextField) {
guard !self.isInputMethod(), let prospectiveText = self.text,
prospectiveText.count > maxLength
else {
return
}
let selection = selectedTextRange
let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
text = prospectiveText.substring(to: maxCharIndex)
selectedTextRange = selection
}
}
Ответ 10
Простое решение без использования делегата:
TEXT_FIELD.addTarget(self, action: #selector(editingChanged(sender:)), for: .editingChanged)
@objc private func editingChanged(sender: UITextField) {
if let text = sender.text, text.count >= MAX_LENGHT {
sender.text = String(text.dropLast(text.count - MAX_LENGHT))
return
}
}
Ответ 11
Этот ответ для Swift 4, и довольно прямолинейный, с возможностью пропускать обратно.
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
return textField.text!.count < 10 || string == ""
}
Ответ 12
Работа в Swift4
//STEP 1 set UITextFieldDelegate
class SignUPViewController: UIViewController , UITextFieldDelegate {
@IBOutlet weak var userMobileNoTextFiled: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
//STEP 2 set delegate
userMobileNoTextFiled.delegate = self//set delegate}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// guard let text = userMobileNoTextFiled.text else { return true }
// let newLength = text.count + string.count - range.length
// return newLength <= 10
// }
//Функция вызова STEP 3
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let maxLength = 10 // set your need
let currentString: NSString = textField.text! as NSString
let newString: NSString =
currentString.replacingCharacters(in: range, with: string) as NSString
return newString.length <= maxLength
}
}
Ответ 13
обновление для этого толстяка ответа
спасибо
extension UITextField {
/// Runtime key
private struct AssociatedKeys {
/// max lenght key
static var maxlength: UInt8 = 0
/// temp string key
static var tempString: UInt8 = 0
}
/// Limit the maximum input length of the textfiled
@IBInspectable var maxLength: Int {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.maxlength) as? Int ?? 0
}
set {
objc_setAssociatedObject(self, &AssociatedKeys.maxlength, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
addTarget(self, action: #selector(handleEditingChanged(textField:)), for: .editingChanged)
}
}
/// temp string
private var tempString: String? {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.tempString) as? String
}
set {
objc_setAssociatedObject(self, &AssociatedKeys.tempString, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
/// When the text changes, process the amount of text in the input box so that its length is within the controllable range.
@objc private func handleEditingChanged(textField: UITextField) {
/// Special Processing for Chinese Input Method
guard markedTextRange == nil else { return }
if textField.text?.count == maxLength {
/// SET lastQualifiedString where text length == max lenght
tempString = textField.text
} else if textField.text?.count ?? 0 < maxLength {
/// clear lastQualifiedString when text lengeht > maxlength
tempString = nil
}
/// keep current text range in arcgives
let archivesEditRange: UITextRange?
if textField.text?.count ?? 0 > maxLength {
/// if text length > maxlength,remove last range,to move to -1 postion.
let position = textField.position(from: safeTextPosition(selectedTextRange?.start), offset: -1) ?? textField.endOfDocument
archivesEditRange = textField.textRange(from: safeTextPosition(position), to: safeTextPosition(position))
} else {
/// just set current select text range
archivesEditRange = selectedTextRange
}
/// main handle string max length
textField.text = tempString ?? String((textField.text ?? "").prefix(maxLength))
/// last config edit text range
textField.selectedTextRange = archivesEditRange
}
/// get safe textPosition
private func safeTextPosition(_ optionlTextPosition: UITextPosition?) -> UITextPosition {
/* beginningOfDocument -> The end of the the text document. */
return optionlTextPosition ?? endOfDocument
}
}
Ответ 14
Вот альтернатива Swift 3.2 +, которая позволяет избежать ненужных манипуляций с строкой. В этом случае максимальная длина равна 10:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text = textField.text ?? ""
return text.count - range.length + string.count <= 10
}
Ответ 15
Я использую этот шаг, сначала установите делегат texfield в viewdidload.
override func viewDidLoad() {
super.viewDidLoad()
textfield.delegate = self
}
а затем следует изменитьCharactersIn после включения UITextFieldDelegate.
extension viewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newLength = (textField.text?.utf16.count)! + string.utf16.count - range.length
if newLength <= 8 {
return true
} else {
return false
}
}
}
Ответ 16
Просто сверьтесь с количеством символов в строке
- Добавить делегата для просмотра контроллера и делегата asign
class YorsClassName : UITextFieldDelegate {
}
- проверьте количество символов, разрешенных для текстового поля
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField.text?.count == 1 {
return false
}
return true
}
Примечание: здесь я проверил только разрешенный символ в textField
Ответ 17
Swift 5
Кредит: http://www.swiftdevcenter.com/max-character-limit-of-uitextfield-and-allowed-characters-swift/
Простонапишите один, чтобы установить максимальную длину символа
self.textField.maxLength = 10
Для более подробной информации нажмите здесь
Ответ 18
Ограничительный символ TextField после блокировки текста в Swift 4
func textField(_ textField: UITextField, shouldChangeCharactersIn range:
NSRange,replacementString string: String) -> Bool
{
if textField == self.txtDescription {
let maxLength = 200
let currentString: NSString = textField.text! as NSString
let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
return newString.length <= maxLength
}
return true
}