Как к контенту перерасположения NSTextView так, чтобы мои символы табуляции были оттянуты с шириной 4 символов

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

Таким образом, текстовое содержание было бы похоже на это:

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:YES myTextView, поскольку я считал, что он заканчивает тем, что назвал setNeedsDisplayInRect:avoidAdditionalLayout NSTextView с НЕ для avoidAdditionalLayout параметра. Это ничего не изменило.

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

Я также попытался говорить layoutManager myTextView к ensureLayoutForTextContainer для textContainer myTextView. Никакое изменение.

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

6
задан Lyndsey Ferguson 26 July 2013 в 11:45
поделиться

2 ответа

Дуглас Дэвидсон из Apple предоставил мне подсказки , чтобы найти ответ через (скрытый) список адресов электронной почты.

Я решил проблему, обновив функцию 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];
}
3
ответ дан 17 December 2019 в 07:03
поделиться

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

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

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

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

1
ответ дан 17 December 2019 в 07:03
поделиться