Как установить максимальное количество символов в UITextField
на iPhone SDK при загрузке UIView
?
Хотя класс UITextField
не имеет свойства max length, относительно просто получить эту функцию, установив delegate
текстового поля и реализовав следующий метод делегата:
Objective-C
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Prevent crashing undo bug – see note below.
if(range.length + range.location > textField.text.length)
{
return NO;
}
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return newLength <= 25;
}
стриж
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentCharacterCount = textField.text?.count ?? 0
if range.length + range.location > currentCharacterCount {
return false
}
let newLength = currentCharacterCount + string.count - range.length
return newLength <= 25
}
Перед изменением текстового поля UITextField спрашивает делегата, должен ли быть изменен указанный текст. На этом этапе текстовое поле не изменилось, поэтому мы берем текущую длину и длину вставляемой строки (либо путем вставки скопированного текста, либо путем ввода одного символа с помощью клавиатуры), за вычетом длины диапазона. Если это значение слишком длинное (более 25 символов в этом примере), верните NO
чтобы запретить изменение.
При вводе одного символа в конце текстового поля range.location
будет текущей длиной поля, а range.length
будет 0, потому что мы ничего не заменяем/не range.length
. Вставка в середину текстового поля означает просто другое расположение range.location
, а вставка нескольких символов означает, что string
содержит более одного символа.
Удаление отдельных символов или вырезание нескольких символов определяется range
с ненулевой длиной и пустой строкой. Замена - это просто удаление диапазона с непустой строкой.
Как уже упоминалось в комментариях, в UITextField
есть ошибка, которая может привести к сбою.
Если вы вставляете в поле, но вставка предотвращается вашей реализацией проверки, операция вставки все еще записывается в буфер отмены приложения. Если вы затем UITextField
отмену (встряхивая устройство и подтверждая отмену), UITextField
попытается заменить строку, которую он считает вставленной в себя, пустой строкой. Это приведет к сбою, потому что он никогда не вставлял строку в себя. Он попытается заменить часть строки, которая не существует.
К счастью, вы можете защитить UITextField
от такого UITextField
. Вам просто нужно убедиться, что диапазон, который он предлагает заменить, существует в его текущей строке. Это то, что делает начальная проверка здравомыслия выше.
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let str = (textView.text + text)
if str.characters.count <= 10 {
return true
}
textView.text = str.substring(to: str.index(str.startIndex, offsetBy: 10))
return false
}
Надеюсь, что это полезно для вас.
Спасибо, август! (Сообщение)
Это код, с которым я закончил работу:
#define MAX_LENGTH 20
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length >= MAX_LENGTH && range.length == 0)
{
return NO; // return NO to not change text
}
else
{return YES;}
}
import UIKit
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)
addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
}
}
@objc func checkMaxLength(textField: UITextField) {
guard let prospectiveText = self.text,
prospectiveText.count > maxLength
else {
return
}
let selection = selectedTextRange
let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
let substring = prospectiveText[..<indexEndOfText]
text = String(substring)
selectedTextRange = selection
}
}
Редактировать: исправлена проблема утечки памяти.
Чтобы завершить ответ Август, возможная реализация предлагаемой функции (см. делегат UITextField).
Я не тестировал код domness, но мой не застревает, если пользователь достиг предела, и он совместим с новой строкой, которая приходит на замену меньшим или равным.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//limit the size :
int limit = 20;
return !([textField.text length]>limit && [string length] > range.length);
}
Вы не можете сделать это напрямую - UITextField
не имеет атрибута maxLength, но вы можете установить делегат UITextField's
, а затем использовать:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
Часто у вас есть несколько полей ввода различной длины.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
int allowedLength;
switch(textField.tag) {
case 1:
allowedLength = MAXLENGTHNAME; // triggered for input fields with tag = 1
break;
case 2:
allowedLength = MAXLENGTHADDRESS; // triggered for input fields with tag = 2
break;
default:
allowedLength = MAXLENGTHDEFAULT; // length default when no tag (=0) value =255
break;
}
if (textField.text.length >= allowedLength && range.length == 0) {
return NO; // Change not allowed
} else {
return YES; // Change allowed
}
}
Лучший способ - настроить уведомление об изменении текста. В -awakeFromNib
вашего метода контроллера вида вы хотите:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(limitTextField:) name:@"UITextFieldTextDidChangeNotification" object:myTextField];
Затем в том же классе добавьте:
- (void)limitTextField:(NSNotification *)note {
int limit = 20;
if ([[myTextField stringValue] length] > limit) {
[myTextField setStringValue:[[myTextField stringValue] substringToIndex:limit]];
}
}
Затем подключите выход myTextField
к вашему UITextField
, и он не позволит вам добавлять больше символов после достижения предела. Не забудьте добавить это к вашему методу dealloc:
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:myTextField];
Я создал this Подкласс UITextFieldLimit:
Возьмите UITextFieldLimit.h
и UITextFieldLimit.m
из этого репозитория GitHub:
https://github.com/JonathanGurebo/UITextFieldLimit
и начните тестирование!
Отметьте созданный раскадрой UITextField и привяжите его к моему подклассу с помощью Identity Inspector:
Затем вы можете связать его с IBOutlet и установить ограничение (по умолчанию 10).
Ваш файл ViewController.h должен содержать: (если вы не хотите изменять настройку, например, ограничение)
#import "UITextFieldLimit.h"
/.../
@property (weak, nonatomic) IBOutlet UITextFieldLimit *textFieldLimit; // <--Your IBOutlet
Ваш файл ViewController.m должен @synthesize textFieldLimit
.
Задайте ограничение длины текста в файле ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[textFieldLimit setLimit:25];// <-- and you won't be able to put more than 25 characters in the TextField.
}
Надеюсь, что класс поможет вам. Удачи!
Этого должно быть достаточно, чтобы решить проблему (замените 4 пределом u want). Просто не забудьте добавить делегата в IB.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
return (newString.length<=4);
}
версия Swift 3 // ***** Это НЕ работает с Swift 2.x! *****//
Сначала создайте новый файл Swift: TextFieldMaxLength.swift, и затем добавьте следующий код:
import UIKit
private var maxLengths = [UITextField: Int]()
extension UITextField {
@IBInspectable var maxLength: Int {
get {
guard let length = maxLengths[self]
else {
return Int.max
}
return length
}
set {
maxLengths[self] = newValue
addTarget(
self,
action: #selector(limitLength),
for: UIControlEvents.editingChanged
)
}
}
func limitLength(textField: UITextField) {
guard let prospectiveText = textField.text,
prospectiveText.characters.count > maxLength
else {
return
}
let selection = selectedTextRange
let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
text = prospectiveText.substring(to: maxCharIndex)
selectedTextRange = selection
}
}
а затем вы увидите в Storyboard новое поле (Max Length), когда вы выберете любой TextField
если у вас есть еще вопросы, посмотрите эту ссылку: http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields-maximum-length-visual-studio-style/
Я смоделирую фактическую замену строки, которая должна произойти, чтобы вычислить длину будущей строки:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if([newString length] > maxLength)
return NO;
return YES;
}
Следующий код похож на ответ "больной", но правильно обрабатывает операции копирования и вставки. Если вы попытаетесь вставить текст, который превышает лимит, следующий код усекает текст, чтобы он соответствовал пределу, а не полностью отказывался от операции вставки.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
static const NSUInteger limit = 70; // we limit to 70 characters
NSUInteger allowedLength = limit - [textField.text length] + range.length;
if (string.length > allowedLength) {
if (string.length > 1) {
// get at least the part of the new string that fits
NSString *limitedString = [string substringToIndex:allowedLength];
NSMutableString *newString = [textField.text mutableCopy];
[newString replaceCharactersInRange:range withString:limitedString];
textField.text = newString;
}
return NO;
} else {
return YES;
}
}
Используя построитель интерфейсов, вы можете связать и получить событие "Редактирование изменено" в любой из ваших функций. Теперь вы можете установить проверку длины
- (IBAction)onValueChange:(id)sender
{
NSString *text = nil;
int MAX_LENGTH = 20;
switch ([sender tag] )
{
case 1:
{
text = myEditField.text;
if (MAX_LENGTH < [text length]) {
myEditField.text = [text substringToIndex:MAX_LENGTH];
}
}
break;
default:
break;
}
}
Существует общее решение для установки максимальной длины в Swift. С IBInspectable вы можете добавить новый атрибут в инспекторе атрибутов XCode.
import UIKit
private var maxLengths = [UITextField: Int]()
extension UITextField {
@IBInspectable var maxLength: Int {
get {
guard let length = maxLengths[self]
else {
return Int.max
}
return length
}
set {
maxLengths[self] = newValue
addTarget(
self,
action: Selector("limitLength:"),
forControlEvents: UIControlEvents.EditingChanged
)
}
}
func limitLength(textField: UITextField) {
guard let prospectiveText = textField.text
where prospectiveText.characters.count > maxLength else {
return
}
let selection = selectedTextRange
text = prospectiveText.substringWithRange(
Range<String.Index>(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
)
selectedTextRange = selection
}
}
Чтобы заставить его работать с вырезанием и вставкой строк любой длины, я бы предложил изменить функцию на что-то вроде:
#define MAX_LENGTH 20
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSInteger insertDelta = string.length - range.length;
if (textField.text.length + insertDelta > MAX_LENGTH)
{
return NO; // the new string would be longer than MAX_LENGTH
}
else {
return YES;
}
}
Этот код работает отлично, когда вы вставляете строку больше, чем ваши ограничения символов.
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let str = (textView.text + text)
if str.characters.count <= 10 {
return true
}
textView.text = str.substring(to: str.index(str.startIndex, offsetBy: 10))
return false
}
Спасибо за ваши голоса.:)
Swift 2.0 +
Прежде всего создайте класс для этого процесса. Позволяет называть его StringValidator.swift.
Затем просто вставьте в него следующий код.
import Foundation
extension String {
func containsCharactersIn(matchCharacters: String) -> Bool {
let characterSet = NSCharacterSet(charactersInString: matchCharacters)
return self.rangeOfCharacterFromSet(characterSet) != nil
}
func containsOnlyCharactersIn(matchCharacters: String) -> Bool {
let disallowedCharacterSet = NSCharacterSet(charactersInString: matchCharacters).invertedSet
return self.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
}
func doesNotContainCharactersIn(matchCharacters: String) -> Bool {
let characterSet = NSCharacterSet(charactersInString: matchCharacters)
return self.rangeOfCharacterFromSet(characterSet) == nil
}
func isNumeric() -> Bool
{
let scanner = NSScanner(string: self)
scanner.locale = NSLocale.currentLocale()
return scanner.scanDecimal(nil) && scanner.atEnd
}
}
Теперь сохраните класс.....
Usage..
Теперь перейдите к классу viewController.swift и создайте свои текстовые поля как..
@IBOutlet weak var contactEntryTxtFld: UITextField! //First textfield
@IBOutlet weak var contactEntryTxtFld2: UITextField! //Second textfield
Теперь перейдите к методу textChangeCharactersInRange и используйте следующее.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if string.characters.count == 0 {
return true
}
let latestText = textField.text ?? ""
let checkAbleText = (latestText as NSString).stringByReplacingCharactersInRange(range, withString: string)
switch textField {
case contactEntryTxtFld:
return checkAbleText.containsOnlyCharactersIn("0123456789") && prospectiveText.characters.count <= 5
case contactEntryTxtFld2:
return checkAbleText.containsOnlyCharactersIn("0123456789") && prospectiveText.characters.count <= 5
default:
return true
}
}
Не забудьте установить делегатский протокол/методы текстовых полей.
Позвольте мне объяснить об этом... Я использую простой процесс расширения строки, который я написал внутри другого класса. Теперь я просто вызываю эти методы расширения из другого класса, где мне это нужно, добавляя проверку и максимальное значение.
Особенности...
Типы...
containsOnlyCharactersIn//принимает только символы.
containsCharactersIn//принимает комбинацию символов
doesNotContainsCharactersIn//Не принимает символы
Надеюсь, это помогло.... Спасибо..
Используйте расширение ниже, чтобы установить максимальную длину символов UITextField
и UITextView
.
Swift 4.0
private var kAssociationKeyMaxLength: Int = 0
private var kAssociationKeyMaxLengthTextView: 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)
addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
}
}
@objc func checkMaxLength(textField: UITextField) {
guard let prospectiveText = self.text,
prospectiveText.count > maxLength
else {
return
}
let selection = selectedTextRange
let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
let substring = prospectiveText[..<indexEndOfText]
text = String(substring)
selectedTextRange = selection
}
}
extension UITextView:UITextViewDelegate {
@IBInspectable var maxLength: Int {
get {
if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLengthTextView) as? Int {
return length
} else {
return Int.max
}
}
set {
self.delegate = self
objc_setAssociatedObject(self, &kAssociationKeyMaxLengthTextView, newValue, .OBJC_ASSOCIATION_RETAIN)
}
}
public func textViewDidChange(_ textView: UITextView) {
checkMaxLength(textField: self)
}
@objc func checkMaxLength(textField: UITextView) {
guard let prospectiveText = self.text,
prospectiveText.count > maxLength
else {
return
}
let selection = selectedTextRange
let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
let substring = prospectiveText[..<indexEndOfText]
text = String(substring)
selectedTextRange = selection
}
}
Вы можете установить предел ниже.
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
}
guard
?
Я даю дополнительный ответ на основе @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)
}
}
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
}
//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
}
}
Для Xamarin:
YourTextField.ShouldChangeCharacters =
delegate(UITextField textField, NSRange range, string replacementString)
{
return (range.Location + replacementString.Length) <= 4; // MaxLength == 4
};
Это правильный способ обработки максимальной длины на UITextField, он позволяет возвращать ключ, чтобы выйти из режима текстового поля в качестве первого ответчика и позволяет пользователю отступать, когда они достигают предела
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
int MAX_LENGHT = 5;
if([string isEqualToString:@"\n"])
{
[textField resignFirstResponder];
return FALSE;
}
else if(textField.text.length > MAX_LENGHT-1)
{
if([string isEqualToString:@""] && range.length == 1)
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return TRUE;
}
}
Если ваша цель ограничить количество слов, чтобы убедиться, что текст будет вписываться в UILabel в другом месте, я бы избегал использовать число символов. Он ломается с некоторыми эможи (попытка усечения двойного размера emoji, скорее всего, приведет к краху вашего приложения). Это также проблема с некоторыми языками, такими как японский и китайский, которые имеют двухэтапный входной процесс, когда простой счет просто не будет работать.
Я построил подкаталог подкаталогов UITextField (MPC_CharacterLimitedTextField в github). Вы кормите его ожидаемой шириной ярлыка вывода, и он будет обрабатывать все языки, emoji и вопросы вставки. Он будет собирать только столько полных символов, которые будут вписываться в метку, независимо от количества символов. Там есть демо в проекте, чтобы вы могли проверить его, чтобы узнать, что вам нужно. Надеюсь, это поможет любому, у кого были те же проблемы с выходной длиной, что и я.
Я сделал это в Swift для ограничения на 8 символов при использовании цифровой клавиатуры.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
return !(textField.text?.characters.count == MAX_LENGTH && string != "")
}
Мне пришлось проверять строку!= "", чтобы кнопка удаления могла работать на цифровой клавиатуре, иначе она не позволила бы удалять символы в текстовом поле после достижения максимального значения.
Используйте этот код здесь RESTRICTED_LENGTH - длина, которую вы хотите ограничить для текстового поля.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == nameTF) {
int limit = RESTRICTED_LENGTH - 1;
return !([textField.text length]>limit && [string length] > range.length);
}
else
{
return YES;
}
return NO;
}
У меня есть открытый подкласс UITextField, STATextField, который предлагает эту функциональность (и многое другое) с ее свойством maxCharacterLength
.
Я добавил расширение UITextField, чтобы добавить к нему свойство maxLength.
Он основан на Xcode 6 IBInspectables, поэтому вы можете установить предел maxLength для построителя интерфейса.
Вот реализация:
UITextField + MaxLength.h
#import <UIKit/UIKit.h>
@interface UITextField_MaxLength : UITextField<UITextFieldDelegate>
@property (nonatomic)IBInspectable int textMaxLength;
@end
UITextField + MaxLength.m
#import "UITextField+MaxLength.h"
@interface UITextField_MaxLength()
@property (nonatomic, assign) id <UITextFieldDelegate> superDelegate;
@end
@implementation UITextField_MaxLength
- (BOOL)textField:(UITextField *) textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//validate the length, only if it set to a non zero value
if (self.textMaxLength>0) {
if(range.length + range.location > textField.text.length)
return NO;
if (textField.text.length+string.length - range.length>self.textMaxLength) {
return NO;
}
}
//if length validation was passed, query the super class to see if the delegate method is implemented there
if (self.superDelegate && [self.superDelegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
return [self.superDelegate textField:textField shouldChangeCharactersInRange:range replacementString:string];
}
else{
//if the super class does not implement the delegate method, simply return YES as the length validation was passed
return YES;
}
}
- (void)setDelegate:(id<UITextFieldDelegate>)delegate {
if (delegate == self)
return;
self.superDelegate = delegate;
[super setDelegate:self];
}
//forward all non overriden delegate methods
- (id)forwardingTargetForSelector:(SEL)aSelector {
if ([self.superDelegate respondsToSelector:aSelector])
return self.superDelegate;
return [super forwardingTargetForSelector:aSelector];
}
- (BOOL)respondsToSelector:(SEL)aSelector {
if ([self.superDelegate respondsToSelector:aSelector])
return YES;
return [super respondsToSelector:aSelector];
}
@end
Доведено до 1 строки кода:)
Установите делегат текстового представления на "self", затем добавьте <UITextViewDelegate>
в ваш .h и следующий код в вашем .m.... вы можете настроить число "7", чтобы быть тем, что вы хотите, чтобы ваше МАКСИМАЛЬНОЕ число символов.
-(BOOL)textView:(UITextView *)a shouldChangeTextInRange:(NSRange)b replacementText:(NSString *)c {
return ((a.text.length+c.length<=7)+(c.length<1)+(b.length>=c.length)>0);
}
Этот код учитывает ввод новых символов, удаление символов, выбор символов, затем ввод или удаление, выбор символов, вырезание, вставка в общем и выбор символов и вставка.
Готово!
:
Альтернативно, еще один классный способ записать этот код с битовыми операциями будет
-(BOOL)textView:(UITextView *)a shouldChangeTextInRange:(NSRange)b replacementText:(NSString *)c {
return 0^((a.text.length+c.length<=7)+(c.length<1)+(b.length>=c.length));
}
теперь сколько символов u хотите просто дать значения
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 25) ? NO : YES;
}
Другие ответы не обрабатывают случай, когда пользователь может вставить длинную строку из буфера обмена. Если я вставлю длинную строку, ее нужно просто усечь, но показать. Используйте это в своем делегате:
static const NSUInteger maxNoOfCharacters = 5;
-(IBAction)textdidChange:(UITextField * )textField
{
NSString * text = textField.text;
if(text.length > maxNoOfCharacters)
{
text = [text substringWithRange:NSMakeRange(0, maxNoOfCharacters)];
textField.text = text;
}
// use 'text'
}
Как насчет этого простого подхода. Это работает нормально для меня.
extension UITextField {
func charactersLimit(to:Int) {
if (self.text!.count > to) {
self.deleteBackward()
}
}
}
Затем:
someTextField.charactersLimit(to:16)
Вы также можете сделать это с помощью NotificationCenter в Swift 4
NotificationCenter.default.addObserver(self, selector: #selector(self.handleTextChange(recognizer:)), name: NSNotification.Name.UITextFieldTextDidChange, object: yourTextField)
@objc func handleTextChange(recognizer: NSNotification) {
//max length is 50 charater max
let textField = recognizer.object as! UITextField
if((textField.text?.count)! > 50) {
let newString: String? = (textField.text as NSString?)?.substring(to: 50)
textField.text = newString
}
}
для Swift 3.1 или более поздней версии
сначала добавьте протокол UITextFieldDelegate
как: -
class PinCodeViewController: UIViewController, UITextFieldDelegate {
.....
.....
.....
}
после этого создайте свой UITextField и установите делегат
Complete Exp: -
import UIKit
class PinCodeViewController: UIViewController, UITextFieldDelegate {
let pinCodetextField: UITextField = {
let tf = UITextField()
tf.placeholder = "please enter your pincode"
tf.font = UIFont.systemFont(ofSize: 15)
tf.borderStyle = UITextBorderStyle.roundedRect
tf.autocorrectionType = UITextAutocorrectionType.no
tf.keyboardType = UIKeyboardType.numberPad
tf.clearButtonMode = UITextFieldViewMode.whileEditing;
tf.contentVerticalAlignment = UIControlContentVerticalAlignment.center
return tf
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(pinCodetextField)
//----- setup your textfield anchor or position where you want to show it-----
// after that
pinCodetextField.delegate = self // setting the delegate
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return !(textField.text?.characters.count == 6 && string != "")
} // this is return the maximum characters in textfield
}
Я хочу добавить к ответу @sickp.
В коде Swift
есть проблема, которая возникает с любым многобайтовым текстом (например, emojis). NSRange
и String
в Swift
несовместимы, поэтому разочарование в том, что класс делегата их объединяет. Хитрость - просто преобразовать объекты String
в NSString
. Правильное решение, основанное на том, что написал @sickp, на самом деле таково:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentText = (textField.text as NSString?) ?? NSString()
let currentCharacterCount = currentText.length
if range.length + range.location > currentCharacterCount {
return false
}
let newLength = currentText.replacingCharacters(in: range, with: string).characters.count
return newLength <= 25
}
Для Swift 2.1 +
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if (range.length + range.location > textField.text!.characters.count )
{
return false;
}
let newLength = textField.text!.characters.count + string.characters.count - range.length
return newLength <= 25
}
Надеюсь, что это поможет
Чуть больше, чем отвечать на исходный вопрос и расширяя ответ Frouo, вот расширения для обрезки строки с пробелом и максимальной длиной и использования этих расширений String для обрезки UITextField до максимальной длины:
// In String_Extensions.swift
extension String {
func trimmedString() -> String {
var trimmedString = self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
let components = trimmedString.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).filter { count($0) > 0 }
return " ".join(components)
}
func trimmedStringToMaxLength(maxLength: Int) -> String {
return trimmedString().substringToIndex(advance(startIndex, min(count(self), maxLength))).trimmedString()
}
}
// In UITextField_Extensions.swift
private var maxLengthDictionary = [UITextField : Int]()
private var textFieldMaxLength = 20
extension UITextField {
@IBInspectable var maxLength: Int {
get {
if let maxLength = maxLengthDictionary[self] {
return maxLength
} else {
return textFieldMaxLength
}
}
set {
maxLengthDictionary[self] = newValue < textFieldMaxLength + 1 ? newValue : textFieldMaxLength
}
}
func trimAndLimitToMaxLength() {
text = text.trimmedStringToMaxLength(maxLength)
}
}
let someTextField = UITextField()
let someString = " This is a string that is longer than allowable for a text field. "
someTextField.text = someString
someTextField.trimAndLimitToMaxLength()
println(someTextField.text) // Prints "This is a string tha"
let anotherTextField = UITextField()
anotherTextField.maxLength = 5
anotherTextField.text = someString
anotherTextField.trimAndLimitToMaxLength()
println(anotherTextField.text) // Prints "This"
trimAndLimitToMaxLength()
может использоваться в UITextFieldDelegate textFieldDidEndEditing(_:)
, чтобы пользователь мог ввести или вставить более длинную, чем приемлемую строку, а затем сократить ее или просто отключить вход на максимальной длине. При этом я также установил атрибутные стили текста, чтобы указать любую часть текста, которая выходит за допустимую длину (например, [NSBackgroundColorAttributeName : UIColor.redColor(), NSForegroundColorAttributeName : UIColor.whiteColor(), NSStrikethroughStyleAttributeName : NSNumber(int: 1)]
Это ограничивает количество символов, но также убедитесь, что вы можете вставлять их в поле до максимального предела.
- (void)textViewDidChange:(UITextView *)textView
{
NSString* str = [textView text];
str = [str substringToIndex:MIN(1000,[str length])];
[textView setText:str];
if([str length]==1000) {
// show some label that you've reached the limit of 1000 characters
}
}
мы можем установить диапазон текстового поля следующим образом.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int setrange = 20;
return !([textField.text length]>setrange && [string length] > range.length);
}
(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([txt_name.text length]>100)
{
return NO;
}
return YES;
}
Проблема с некоторыми из приведенных выше ответов: Например, у меня есть текстовое поле, и я должен установить ограничение на 15 символов, а затем останавливается после ввода 15-го символа. но они не позволяют удалять. То есть кнопка удаления также не работает. Поскольку я столкнулся с той же проблемой. Вышел с решением, приведенным ниже. Работает идеально для меня
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField.tag==6)
{
if ([textField.text length]<=30)
{
return YES;
}
else if([@"" isEqualToString:string])
{
textField.text=[textField.text substringToIndex:30 ];
}
return NO;
}
else
{
return YES;
}
}
У меня есть текстовое поле, чей тег я установил "6" и я ограничил max char limit = 30; отлично работает в каждом случае
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField.text.length >= 50) {
return NO;
}
return YES;
}
Я нашел это быстро и просто
- (IBAction)backgroundClick:(id)sender {
if (mytext.length <= 7) {
[mytext resignFirstResponder];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Too Big"
message:@"Please Shorten Name"
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
UIAlertView
s не рекомендуется Apple. Вы должны зарезервировать оповещения для важных сообщений и просто запретить ввод, как в принятом ответе.