2010-02-17 1 views
6

Я работаю с NSTextView, и одно из требований, которое у меня есть, состоит в том, что символ табуляции '\ t' должен иметь одинаковый ширину как четыре пробела.Как передать содержимое NSTextView так, чтобы мои символы вкладок были нарисованы с шириной в 4 символа.

Таким образом, текст-контент будет выглядеть следующим образом:

AAAA 
    AAAA - 1 tab 
    AAAA - 4 spaces 

И это, как я сделать это:

// done when NSTextView first loaded and when 
// delegate's textDidBeginEditing gets called: (perhaps overkill, but is a work in progress). 
- (void)updateMyTextViewTextAttributes 
{ 
    NSMutableParagraphStyle* paragraphStyle = [[myTextView defaultParagraphStyle] mutableCopy]; 
    if (paragraphStyle == nil) { 
     paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 
    } 
    float charWidth = [[myFont screenFontWithRenderingMode:NSFontDefaultRenderingMode] advancementForGlyph:(NSGlyph) ' '].width; 
    [paragraphStyle setDefaultTabInterval:(charWidth * 4)]; 
    [paragraphStyle setTabStops:[NSArray array]]; 
    [myTextView setDefaultParagraphStyle:paragraphStyle]; 

    NSMutableDictionary* typingAttributes = [[myTextView typingAttributes] mutableCopy]; 
    [typingAttributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName]; 
    [typingAttributes setObject:scriptFont forKey:NSFontAttributeName]; 
    [myTextView setTypingAttributes:typingAttributes]; 
} 

Это позволяет раскладку быть показаны с исходным текстом, а также так как сохраняйте атрибуты ввода одинаковыми.

Проблема в том, что конечный пользователь может изменить шрифт. И когда это произойдет, образец текста будет смещен. Многое, как показано ниже:

[smaller font] 
AAAA 
    AAAA - 1 tab 
    AAAA - 4 spaces 


[larger font] 
AAAA 
    AAAA - 1 tab 
    AAAA - 4 spaces 

Я пытался дозвониться setNeedsDisplay myTextView в: ДА, как я прочитал, что он заканчивает вызовом setNeedsDisplayInRect NSTextView в: avoidAdditionalLayout с NO для параметра avoidAdditionalLayout. Это ничего не изменило.

Я попытался вызвать мой вызов updateMyTextViewTextAttributes, когда myTextView имеет новый набор myFont. Это ничего не меняет.

Я также попробовал передать layoutManager myTextView для обеспеченияLayoutForTextContainer для textContainer myTextView. Без изменений.

На данный момент я не уверен, что делать дальше. Какие-либо предложения?

ответ

3

Дуглас Дэвидсон компании Apple предоставила мне clues, чтобы добраться до ответа через список [email protected] электронной почты.

Я решил проблему путем обновления updateMyTextViewTextAttributes функционировать следующим образом:

- (void)updateMyTextViewTextAttributes 
{ 
   NSMutableParagraphStyle* paragraphStyle = [[myTextView defaultParagraphStyle] mutableCopy]; 

   if (paragraphStyle == nil) { 
       paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 
   } 

   float charWidth = [[myFont screenFontWithRenderingMode:NSFontDefaultRenderingMode] advancementForGlyph:(NSGlyph) ' '].width; 
   [paragraphStyle setDefaultTabInterval:(charWidth * 4)]; 
   [paragraphStyle setTabStops:[NSArray array]]; 

   [myTextView setDefaultParagraphStyle:paragraphStyle]; 

   NSMutableDictionary* typingAttributes = [[myTextView typingAttributes] mutableCopy]; 
   [typingAttributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName]; 
   [typingAttributes setObject:scriptFont forKey:NSFontAttributeName]; 
   [myTextView setTypingAttributes:typingAttributes]; 

    /** ADDED CODE BELOW **/ 
   NSRange rangeOfChange = NSMakeRange(0, [[myTextView string] length]); 
   [myTextView shouldChangeTextInRange:rangeOfChange replacementString:nil]; 
   [[myTextView textStorage] setAttributes:typingAttributes range:rangeOfChange]; 
   [myTextView didChangeText]; 

    [paragraphStyle release]; 
    [typingAttributes release]; 
} 
1

Вы пытались вычислить космическое продвижение с advancementForGlyph: непосредственно на шрифте вместо шрифта экрана?

float charWidth = [myFont advancementForGlyph:(NSGlyph) ' '].width; 

шрифта экран не предназначен для использования непосредственно вне сервера окна:

Экранные шрифты предназначены для непосредственного использования с только сервер окно. Никогда не используйте их с объектами Application Kit, такими как в методах setFont:. Внутренний набор приложений автоматически использует соответствующий экранный шрифт для шрифта объект, если вид не повернут или масштабируется.

+0

Я нашел фрагмент кода: «[[MyFont screenFontWithRenderingMode: NSFontDefaultRenderingMode] advancementForGlyph: (NSGlyph) '«]. ширина;" в режиме онлайн в некотором коде, описанном для обработки программно заданных ширины табуляции.Если я изменил его на просто: "[myFont advancementForGlyph: (NSGlyph) ''] .width;", линии больше не совпадают. То, что вы указали из документации, есть, но у нее нет одинаковой желаемой функциональности ... –

 Смежные вопросы

  • Нет связанных вопросов^_^