Какао (Snow Leopard) NSTextView textStorage -setAttributes: range: удаляет символы!

Я не уверен, что делаю не так. У меня есть NSTextView, и я зарегистрирован в качестве делегата для его атрибута textStorage. Когда я получаю -textStorageDidProcessEditing:notification:, я пытаюсь применить атрибуты к диапазонам символов в тексте. Это определенно "что-то" делает с персонажами, но не то, что я ожидал ... они просто исчезают!

Пример сильно переработанного кода. Это должно гарантировать, что второй символ в текстовом поле всегда будет красным:

-(void)textStorageDidProcessEditing:(NSNotification *)notification {
  NSTextStorage *textStorage = [textView textStorage];
  if ([[textStorage string] length] > 1) {
    NSColor *color = [NSColor redColor];
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:color, NSForegroundColorAttributeName, nil];
    [textStorage setAttributes:attributes range:NSMakeRange(1, 1)];
  }
}

Вместо этого, когда я набираю последовательность «abcdefg», я получаю «a», затем, когда я нажимаю «b», по-видимому, ничего не происходит, затем, когда я нажимаю «cdefg», ввод происходит как обычно, в результате чего получается «acdefg» ... "b" отсутствует!

Если я начну нажимать Backspace, мне придется 7 раз нажать Backspace, как если бы «b» на самом деле там, но просто не рисовалось (курсор останавливается, поскольку он удаляет «b», затем на следующем backspace удаляет «a» как ожидал).

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

Какие-нибудь подсказки? Вроде нормальное использование NSTextStorageDelegate :)

Я безуспешно пытался вызвать -setNeedsDisplay в текстовом поле.


person d11wtq    schedule 21.10.2010    source источник
comment
Я наткнулся на чужой код, и они сделали это через диспетчер компоновки текстового представления: [[[textView textContainer] layoutManager] setTemporaryAttributes:attributes forCharacterRange:range]; Теперь это работает, вплоть до тех пор, пока я не нажму клавишу удаления, что вызовет исключение за пределами допустимого диапазона.   -  person d11wtq    schedule 22.10.2010
comment
«Если я начну нажимать backspace, мне придется 7 раз нажать backspace, как если бы буква b на самом деле была там, но просто не рисовалась (курсор останавливается, когда удаляет b, а затем на следующем backspace удаляет a, как ожидалось)». Похоже на то, что происходит, когда в приложении возникает исключение. Что-нибудь подобное в вашей консоли?   -  person Peter Hosey    schedule 22.10.2010


Ответы (2)


Догадаться. Использование -addAttribute:value:range от NSTextStorage работает. Я до сих пор не совсем понимаю, почему, но, по крайней мере, я могу преодолеть это и двигаться дальше.

-(void)textStorageDidProcessEditing:(NSNotification *)notification {
  // ... SNIP ...
  [textStorage addAttribute:NSForegroundColorAttributeName
                      value:[NSColor redColor]
                      range:NSMakeRange(1, 1)];
}

Делает код менее загроможденным.

person d11wtq    schedule 22.10.2010

Я не уверен, насколько это актуально для вас после стольких лет, но я думаю, что причиной этого было то, что вы устанавливали атрибуты со словарем, который не содержит NSFontAttributeName, эффективно удаляя его из текстового представления .

Поэтому я думаю, что это должно сработать:

-(void)textStorageDidProcessEditing:(NSNotification *)notification {
  NSTextStorage *textStorage = [textView textStorage];
  if ([[textStorage string] length] > 1) {
    NSColor *color = [NSColor redColor];
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:color, NSForegroundColorAttributeName, [NSFont ...whatever...], NSFontAttributeName, nil];
    [textStorage setAttributes:attributes range:NSMakeRange(1, 1)];
  }
}
person Ecir Hana    schedule 13.12.2014