Как реализовать простое «живое» количество слов в UITextView - PullRequest
13 голосов
/ 10 марта 2011

Я пытаюсь реализовать простой счетчик символов UITextView, когда пользователь печатает текст (т. Е. Он должен постоянно обновляться).

У меня две проблемы.

(1Во-первых, я не знаю, в какой метод я должен поместить свой метод charCount.textViewShouldBeginEditing не работает, так как он просто спрашивает, следует ли начинать сеанс редактирования.textView: shouldChangeTextInRange также не работает, так как он снова спрашивает, разрешено ли начинать редактирование.Я не смог найти другие полезные методы в Apple doc.

(2) Следующая проблема: я попытался вызвать свой метод charCount из другого метода.Но я получаю ошибку компилятора: «ViewController» может не отвечать на «charCount».

Вот моя скромная попытка:

- (IBAction)charCount:(id)sender {

// all chars
int charsAsInt = (int)(textView.text.length);
NSString *newText = [[NSString alloc] initWithFormat:@"All chars: %d", charsAsInt];
allCharacters.text = newText;
[newText release];}

- (BOOL)textViewShouldBeginEditing:(UITextView *)aTextView {

    [self charCount];}

Я думаю, это связано со мной, пытаясь вызватьметод, определенный IBAction, который не будет работать.Но как правильно вызвать метод IBAction из не-IBAction метода?

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

Ответы [ 9 ]

50 голосов
/ 10 марта 2011

Раньше я создавал так, чтобы UITextview печатал только 140 символов.
И я показал, что считать в UILabel вот так

-(void)textViewDidChange:(UITextView *)textView 
{
   int len = textView.text.length;
   lbl_count.text=[NSString stringWithFormat:@"%i",140-len];
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    if([text length] == 0)
    {
        if([textView.text length] != 0)
        {
            return YES;
        }
    }
    else if([[textView text] length] > 139)
    {
        return NO;
    }
    return YES;
} 

это может помочь тебе !!!

6 голосов
/ 10 марта 2011

textView: shouldChangeTextInRange также не работает, так как он снова спрашивает, разрешено ли начинать редактирование.

но ничто не помешает вам подсчитать количество символов там же. Просто верните ДА в конце.

Полагаю, это связано со мной, пытающейся вызвать метод, определенный IBAction, который не будет работать

Вы можете позвонить в IBActions из кода. IBAction - это просто ключевое слово для Interface Builder, но оно такое же, как void.

Но вы должны использовать правильную сигнатуру метода.
Ваш метод - (IBAction)charCount:(id)sender имеет один параметр (идентификатор отправителя)
Но у вашего звонка [self charCount] нет параметра.

измените его на [self charCount:nil] и все будет в порядке.


Edit: у меня сейчас нет textView, и я слишком ленив, чтобы создать его сейчас, но это работает с UITextField:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSInteger textLength = 0;
    textLength = [textField.text length] + [string length] - range.length;
    NSLog(@"Length: %d", textLength);
    return YES;
}

Я добавляю длину замещающей строки к текущему тексту поля. Затем я вычитаю длину диапазона замены.
Вам следует поэкспериментировать, чтобы лучше понять связь между этими 3.
В основном, если вы перезаписываете какой-то текст, длина диапазона будет равна длине текста, который вы хотите перезаписать (т.е. длина выделенного текста)

2 голосов
/ 01 ноября 2013

Спасибо n.evermind и Mathias Bauch за их вклад.Ниже мое решение для UITextField , которое объединяет информацию из обоих и работает как талисман, чтобы установить ограничение на количество символов, а также визуализировать метку, которая отслеживает текущие символы для пользователя.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    int maxLength = 40;
    int textLength = [textField.text length] + [string length] - range.length;

    if(textLength > maxLength)
    {
        return NO;
    }
    else
    {
        //self.currentLabel in this case is just a UILabel
        //it formats the counter like: 0/40
        self.currentLabel.text = [NSString stringWithFormat:@"%i/%i",textLength,maxLength];
        return YES;
    }
}

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

2 голосов
/ 16 августа 2013

Все, что вам нужно - это реализация делегата textViewDidChange в вашем коде. Вот пример реализации, которая может вам понадобиться:

    #pragma-mark TextView Delegates

- (void)textViewDidChange:(UITextView *)textView
{
    NSLog(@"len:%d",textView.text.length);
    txtLength=textView.text.length;
    lblString=[NSString stringWithFormat:@"%i",210-txtLength];
    if(txtLength>200)
    {
        charactersLabel.textColor=[UIColor redColor];
    }
    charactersLabel.text=lblString;
}

Объявите три используемые переменные в заголовке как:

int txtLength;
NSString *lblString;
IBOutlet UILabel *charactersLabel;

Этикетка печатает символы слева, когда вы продолжаете печатать, и ее цвет меняется на красный, когда вы выходите за пределы 200 здесь. Наконец, не забудьте подключить делегат TextView к владельцу файла и добавить реализацию для UITextViewDelegate в заголовочный файл. Надеюсь, это поможет ..

1 голос
/ 24 января 2014

Фрагмент кода, чтобы подсчет слов в реальном времени обновлял пользовательский интерфейс цветом.

#define kCharacterMaximumLimit 120
#define kCharacterWarningLimit 110

- (void)textViewDidChange:(UITextView *)textView {
    NSString *substring = [NSString stringWithString:textView.text];
    _lblCount.text = [NSString stringWithFormat:@"%i", kCharacterMaximumLimit-[substring length]];

    if (substring.length == 0)
        _lblCount.text = @"";

    if (substring.length < kCharacterWarningLimit)
        _lblCount.textColor = [UIColor darkGrayColor];

    if (substring.length >= kCharacterWarningLimit && substring.length < kCharacterMaximumLimit)
        _lblCount.textColor = [UIColor redColor];
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    if([text length] == 0)
    {
        if([textView.text length] != 0)
            return YES;
        else
            return NO;
    }

    if([[textView text] length] > kCharacterMaximumLimit-1)
        return NO;

    return YES;
}
1 голос
/ 24 июля 2013

Вы можете использовать этот код, скажем, вы хотите, чтобы в вашем представлении было только 10 символов, а также хотите обновить счетчик.

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

-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    NSInteger textLength = 0;
    textLength = [textView.text length] + [text length] - range.length;
    if(10-textLength==-1)
    {
        return NO;
    }
    coutLabel.text = [NSString stringWithFormat:@"%d characters remaining", 10-textLength];

    return YES;}
0 голосов
/ 17 ноября 2015

Здесь мы идем на лучший Fit.

var charCount = 0;
let maxLength = 150
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {

    if text == "" // Checking backspace
    {
        if textView.text.characters.count == 0
        {
            charCount = 0
            characterCount.text = String(format: "%i Characters Left", maxLength - charCount)
            return false
        }
        charCount = (textView.text.characters.count - 1)
        characterCount.text = String(format: "%i Characters Left", maxLength - charCount)
      return true
    }
    else
    {
        charCount = (textView.text.characters.count + 1)
        characterCount.text = String(format: "%i Characters Left", maxLength - charCount)

        if charCount >= maxLength + 1
        {
            charCount = maxLength
            characterCount.text = String(format: "%i Characters Left", maxLength - charCount)
            return false;
        }
    }
    return true
}
0 голосов
/ 19 апреля 2011

более простой способ для noobs - реализовать NStimer, который проверяет длину каждую секунду

для этого добавьте "NSTimer countTimer;" к вашему .h, а затем добавьте это к вашему .m

- (void) viewDidLoad {

countTimer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(countTextView) userInfo:nil repeats:YES];

}

- (недействительными) countTextView {

[countTimer invalidate];
int currentChars = [TextView.text length];

if ([TextView.text length]>100) {
    UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Too long"
        message:[NSString stringWithFormat:@"Only 100 chars allowed."]
        delegate:nil
        cancelButtonTitle:@"OK"
        otherButtonTitles:nil];
    [alert show];
    [alert release];
    TextView.text = [TextView.text substringToIndex:100];
}

counterLabel.text = [NSString stringWithFormat:@"%d",currentChars];

countTimer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(countTextView) userInfo:nil repeats:YES];

}

0 голосов
/ 10 марта 2011

@ fluchtpunkt: чудесно работает! Вот обновленный код на случай, если другой новичок будет искать ответ:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

[self charCount:nil];

// let the textView know that it should handle the inserted text
return YES; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...