Как реализовать простое "живое" количество слов в UITextView

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

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

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

(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?

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

Ответы

Ответ 1

Я использовал для создания так, чтобы запретить 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;
} 

это может помочь вам!!!

Ответ 2

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

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

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

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

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

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


Изменить: у меня нет текстового элемента прямо сейчас, и я слишком ленив, чтобы создать его сейчас, но это работает с 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

Все, что вам нужно использовать, - это реализация делегата 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 в файл заголовка. Надеюсь, что это поможет.

Ответ 4

Благодаря 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;
    }
}

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

Ответ 5

Вы можете использовать этот код, чтобы сказать, что вам нужно только 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;}

Ответ 6

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

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

Ответ 7

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

Ответ 8

Здесь мы идем для лучшего 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
}

Ответ 9

более простой способ для 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];

}