Установите максимальную длину символа UITextField

Для простых задач в среде Unix-ish попробуйте popen() .

На странице man:

Функция popen () открывает процесс, создавая канал, разворачивая и вызывая оболочку.

blockquote>

Если вы используете режим чтения, это именно то, о чем вы просили. Я не знаю, реализована ли она в Windows.

Для более сложных проблем вы хотите искать межпроцессное общение.

461
задан JasonMArcher 24 November 2014 в 17:52
поделиться

7 ответов

Хотя класс UITextField не имеет свойства максимальной длины, получить эту функциональность относительно просто, установив делегат текстового поля и реализовав следующий делегат метод:

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;
}

Swift

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 , чтобы запретить изменение.

При вводе одного символа в конце текстового поля диапазон. location будет длиной текущего поля, а range.length будет иметь значение 0, потому что мы ничего не заменяем / не удаляем. Вставка в середину текстового поля просто означает другое range.location , а вставка нескольких символов просто означает, что строка содержит более одного символа.

Удаление отдельных символов или вырезание нескольких символов определяется диапазоном с ненулевой длиной и пустой строкой. Замена - это просто удаление диапазона с непустой строкой.

Замечание об отказе от ошибки «отменить»

Как упоминалось в комментариях, есть ошибка с UITextField , которая может привести к к сбою.

Если вы вставляете в поле, но вставка предотвращается вашей реализацией проверки, операция вставки все еще записывается в буфере отмены приложения. Если вы затем выполните отмену (встряхнув устройство и подтвердив отмену), UITextField попытается заменить строку, которую он считает вставленной в себя, пустой строкой. Это приведет к сбою, потому что он никогда на самом деле не вставлял строку в себя. Он попытается заменить несуществующую часть строки.

К счастью, вы можете защитить UITextField от подобного самоубийства. Вам просто нужно убедиться, что диапазон, который он предлагает заменить , действительно существует в пределах его текущей строки. Это то, что делает начальная проверка работоспособности выше.

swift 3.0 с копированием и вставкой работает нормально.

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
    }

Надеюсь, это поможет вам.

Если вы затем выполните отмену (встряхнув устройство и подтвердив отмену), UITextField попытается заменить строку, которую он считает вставленной в себя, пустой строкой. Это приведет к сбою, потому что он никогда на самом деле не вставлял строку в себя. Он попытается заменить несуществующую часть строки.

К счастью, вы можете защитить UITextField от подобного самоубийства. Вам просто нужно убедиться, что диапазон, который он предлагает заменить , действительно существует в пределах его текущей строки. Это то, что делает начальная проверка работоспособности выше.

swift 3.0 с копированием и вставкой работает нормально.

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
    }

Надеюсь, это поможет вам.

Если вы затем выполните отмену (встряхнув устройство и подтвердив отмену), UITextField попытается заменить строку, которую он считает вставленной в себя, пустой строкой. Это приведет к сбою, потому что он никогда на самом деле не вставлял строку в себя. Он попытается заменить несуществующую часть строки.

К счастью, вы можете защитить UITextField от такого самоубийства. Вам просто нужно убедиться, что диапазон, который он предлагает заменить , действительно существует в пределах его текущей строки. Это то, что делает начальная проверка работоспособности выше.

swift 3.0 с копированием и вставкой работает нормально.

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
    }

Надеюсь, это поможет вам.

UITextField попытается заменить строку, которую он считает вставленной в себя, пустой строкой. Это приведет к сбою, потому что он никогда на самом деле не вставлял строку в себя. Он попытается заменить несуществующую часть строки.

К счастью, вы можете защитить UITextField от подобного самоубийства. Вам просто нужно убедиться, что диапазон, который он предлагает заменить , действительно существует в пределах его текущей строки. Это то, что делает начальная проверка работоспособности выше.

swift 3.0 с копированием и вставкой работает нормально.

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
    }

Надеюсь, это поможет вам.

UITextField попытается заменить строку, которую он считает вставленной в себя, пустой строкой. Это приведет к сбою, потому что он никогда на самом деле не вставлял строку в себя. Он попытается заменить несуществующую часть строки.

К счастью, вы можете защитить UITextField от такого самоубийства. Вам просто нужно убедиться, что диапазон, который он предлагает заменить , действительно существует в пределах его текущей строки. Это то, что делает начальная проверка работоспособности выше.

swift 3.0 с копированием и вставкой работает нормально.

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
    }

Надеюсь, это поможет вам.

не существует.

К счастью, вы можете защитить UITextField от такого самоубийства. Вам просто нужно убедиться, что диапазон, который он предлагает заменить , действительно существует в пределах его текущей строки. Это то, что делает начальная проверка работоспособности выше.

swift 3.0 с копированием и вставкой работает нормально.

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
    }

Надеюсь, это поможет вам.

t существует.

К счастью, вы можете защитить UITextField от самоубийства таким образом. Вам просто нужно убедиться, что диапазон, который он предлагает заменить , действительно существует в пределах его текущей строки. Это то, что делает начальная проверка работоспособности выше.

swift 3.0 с копированием и вставкой работает нормально.

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
    }

Надеюсь, это поможет вам.

1017
ответ дан 22 November 2019 в 22:53
поделиться

Вы не можете сделать, это непосредственно - UITextField не имеет никакого атрибут maxLength, но можно установить эти UITextField's делегат, затем использовать:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
17
ответ дан etolstoy 25 November 2014 в 03:52
поделиться
  • 1
    @EricLippert: Tyvm для Вашей реакции, я решил это путем сохранения его к assmebly и использования reflector/ilspy. Tnx снова. – Jeroen van Langen 10 October 2013 в 07:17

Лучший способ состоял бы в том, чтобы настроить уведомление на текстовом изменении. В Вашем -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];
12
ответ дан Paulo Moura 25 November 2014 в 03:52
поделиться

Спасибо август! ( Сообщение )

Это - код, что я закончил с который работы:

#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;}
}
56
ответ дан Community 25 November 2014 в 03:52
поделиться
  • 1
    Спасибо за ответ. Это просто делает отвратительный код I' ve наследовался еще хуже, чем я думал, что это было! – Rich Turner 11 January 2011 в 11:42

Чтобы завершить август ответ, возможная реализация предложенной функции (см. UITextField's делегат ).

Я не тестировал код 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);
}
22
ответ дан 22 November 2019 в 22:53
поделиться

Чтобы заставить его работать с вырезанием и вставкой строк любой длины, я бы предложил изменить функцию на что-то вроде:

#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;
        }
    }
5
ответ дан 22 November 2019 в 22:53
поделиться

Я нашел это быстро и просто

- (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];
    }
}
-6
ответ дан 22 November 2019 в 22:53
поделиться