Ваш контроллер представления должен соответствовать 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
}
Для Быстрого 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, которое берет только числовой вход с максимальной длиной
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
}
На всякий случай не забывайте охранять размер диапазона прежде, чем применить его к строке. Иначе Вы получите катастрофический отказ, если пользователь сделает это:
текст продолжительности максимума Типа Вставляет что-то (Ничто не будет вставлено из-за ограничения длины, но iOS не знает об этом), вставка Отмены (Вы получаете катастрофический отказ, диапазон причины будет больше, чем фактический размер строки)
кроме того, с помощью iOS, 13 пользователей могут случайно инициировать это жестами
, я предлагаю, чтобы Вы добавили к своему проекту это
extension String {
func replace(with text: String, in range: NSRange) -> String? {
guard range.location + range.length <= self.count else { return nil }
return (self as NSString).replacingCharacters(in: range, with: text)
}
}
И использовали его как это:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
guard let newText = textView.text.replace(with: text, in: range) else { return false }
return newText.count < maxNumberOfCharacters
}
Иначе, Вы будете постоянно становиться разрушенными в своем приложении
Быстро 5
Кредит: http://www.swiftdevcenter.com/max-character-limit-of-uitextfield-and-allowed-characters-swift/
Просто пишет, что для установки макс. символьной длины
self.textField.maxLength = 10
Для большего количества detial щелкает здесь
Просто просто сверьтесь с количеством символов в строке
class YorsClassName : UITextFieldDelegate {
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField.text?.count == 1 {
return false
}
return true
}
: Здесь я проверил только на символ, позволенный в текстовом поле
Я использую этот шаг, первый делегат Набора texfield в viewdidload.
override func viewDidLoad() {
super.viewDidLoad()
textfield.delegate = self
}
и затем shouldChangeCharactersIn после включения 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
}
}
}
Вот Быстрые 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
}
Работа В Swift4
//ШАГ 1 установил UITextFieldDelegate
class SignUPViewController: UIViewController , UITextFieldDelegate {
@IBOutlet weak var userMobileNoTextFiled: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
//делегат набора ШАГА 2
userMobileNoTextFiled.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
// }
//func
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
}
}
вызова ШАГА 3 обновление для этого ответ Fattie
спасибо
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
}
}
Этот ответ для Swift 4 и является довольно прямым со способностью пропустить клавишу Backspace.
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
return textField.text!.count < 10 || string == ""
}
Мои Быстрые 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
}
Я даю дополнительный ответ на основе @Frouo. Я думаю, что его ответ является самым красивым путем. Becuase это - общий контроль, который мы можем снова использовать. И здесь нет никакой проблемы утечки.
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
}
}
Другие решения отправили выше продукта сохранить цикл из-за карты текстового поля. Кроме того, maxLength
свойство должно быть nullable, если бы не установил вместо искусственного 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
}
}
Swift 4, просто используйте:
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return range.location < 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
}
}
Заботятся, что большая часть примера кода, который Вы будете видеть онлайн относительно этой проблемы, очень устаревшая .
Вставка следующее в любой файл Swift в Вашем проекте. Можно назвать файл чем-либо, например, "Handy.swift"
Ваши текстовые поля теперь имеют .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) }
}
Уф! Вот и все.
(Просто BTW, вот подобная очень полезная подсказка, касающаяся Представления UIText , https://stackoverflow.com/a/42333832/294884)
Тем же путем Steven Schmatz сделал это, но 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
}
У меня есть что-то для добавления к ответу Aladin:
Ваш контроллер представления должен соответствовать UITextFieldDelegate
class MyViewController: UIViewController, UITextViewDelegate {
}
Набор делегат Вашего текстового поля: Для установки делегата можно управлять, перетаскивают с текстового поля на контроллер представления в раскадровке. Я думаю, что это предпочтительно для установки его в коде
Реализация метод в Вашем контроллере представления: textField(_:shouldChangeCharactersInRange:replacementString:)
Я думаю, что расширение более удобно для этого. См. полный ответ здесь
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
}
}