Подсчитайте и измените цвет текста вхождений строки в NSTextView

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

введите здесь описание изображения

Я искал слово «Проверено», и это дало мне следующие результаты.

Ниже приведен код, который я использую

NSArray * lines = [words componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
    wordresult = [lines componentsJoinedByString:@""];





if (occS2 == 1)
    {
        NSString * box2 = [_occSearchTwoTextBox stringValue];
        NSUInteger countFatal = 0, length4 = [wordresult length];
        NSRange range4 = NSMakeRange(0, length4);
        while(range4.location != NSNotFound)
        {
            range4 = [wordresult rangeOfString: box2 options:NSCaseInsensitiveSearch range:range4];

            [self.stringLogTextView setTextColor:[NSColor redColor] range:range4];
            NSLog(@"Occurance Edited");

            if(range4.location != NSNotFound)
            {
                range4 = NSMakeRange(range4.location + range4.length, length4 - (range4.location + range4.length));
                countFatal++;
            }
        }
        NSString * FatalCount = [NSString stringWithFormat:@"%lu", (unsigned long)countFatal];
        [_customSearchTwoTextBox setStringValue:FatalCount];
    }

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

Спасибо всем за время!


person Breathable    schedule 30.10.2014    source источник


Ответы (1)


Я не уверен, почему ваш метод не работает правильно, но я бы сделал это по-другому. Используя enumerateSubstringsInRange:options:usingBlock:, вы можете перечислить свою строку по словам и получить диапазон каждого слова, переданного в метод для вас. Если слово «Проверено», вы можете увеличить свой счетчик, а также установить атрибуты для этого диапазона строки с изменяемым атрибутом. Вот пример того, как использовать этот метод,

    NSString *theText = @"] Tables initialized\n]Database version Checked\n]Got login id-1\n] Tables initialized\n]Database version Checked\n]Got login id-1\n] Tables initialized\n]Database version Checked\n]Got login id-1\n";
    NSMutableAttributedString *attrib = [[NSMutableAttributedString alloc] initWithString:theText];
    NSDictionary *dict = @{NSForegroundColorAttributeName:[NSColor greenColor]};

    __block int count = 0;
    [theText enumerateSubstringsInRange:NSMakeRange(0, theText.length) options:NSStringEnumerationByWords usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
        if ([substring isEqualToString:@"Checked"]) {
            [attrib setAttributes:dict range:substringRange];
            count ++;
        };
    }];

    self.textView.textStorage.attributedString = attrib;
    NSLog(@"count is: %d",count);

введите здесь описание изображения

person rdelmar    schedule 31.10.2014
comment
Ваш пример отлично работает сам по себе, но когда я подключаю его к моему текстовому представлению, он не работает так, как задумано. Он удаляет разрывы строк в текстовом представлении, даже когда я меняю setAttributes на addAttributes, и он не меняет цвет текста, а также говорит, что счетчик равен 0. - person Breathable; 31.10.2014
comment
Что такое строка в вашем текстовом представлении? Это NSString или атрибутированная строка? Как вы передаете строку текстового представления методу перечисления? - person rdelmar; 31.10.2014
comment
Когда я отследил, где я заполняю представление, я обнаружил свою ошибку, я тянул не ту строку. Мои извинения мои плохие. Теперь он отлично работает. Спасибо за вашу помощь @rdelmar - person Breathable; 31.10.2014
comment
Вот дополнительный вопрос, мне нужно выполнить несколько поисков в одном файле журнала. С помощью этого метода я буду искать первый, затем второй, но второй переопределяет первые атрибуты и показывает только второй искомый текст. Не уверен, что это должен быть дополнительный вопрос, но как показать оба поиска. Например, как мне получить Checked и версию, чтобы показать зеленый цвет из 2 методов? - person Breathable; 31.10.2014
comment
Я на самом деле понял это, извините еще раз мои собственные ошибки. - person Breathable; 31.10.2014
comment
по мере того, как я продвигаюсь вперед с поиском вхождений в файлах журналов, я обнаруживаю, что из приведенного выше примера я ищу Checked, код найдет его, но ЕСЛИ я ищу версию Checked, он не находит ее, но ищет отдельные слова version или Checked it работает. Я ищу одну ошибку: Не удалось подключиться к Postgres, как мне искать подстроки с несколькими словами с пробелами? - person Breathable; 06.11.2014
comment
Другой пример: 123Checked не найден при поиске Checked - person Breathable; 06.11.2014
comment
@Breathable, эти новые условия, которые вы ставите перед поиском, значительно меняют характер проблемы. Случай 123Checked можно довольно легко обработать, проверив подстроку hasPrefix: (и hasSuffix, если вы также хотите такую ​​возможность) в дополнение к isEqualToString. Проверка нескольких слов будет сложнее. Вам нужно будет отслеживать предыдущую подстроку, и когда вы найдете Checked, посмотрите на эту предыдущую подстроку и посмотрите, соответствует ли она версии. В зависимости от того, сколько других странных случаев есть, вам может понадобиться совершенно другой подход. - person rdelmar; 06.11.2014
comment
Хорошо звучит хорошо, я буду играть с ним. Большое спасибо за Вашу помощь! - person Breathable; 06.11.2014