Я работаю с 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. Никакое изменение.
На данном этапе я не уверен, что попробовать затем. Какие-либо предложения?
Дуглас Дэвидсон из 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];
}
Пробовали ли вы вычислить продвижение пространства с помощью advancementForGlyph:
непосредственно на шрифте вместо экранного шрифта?
float charWidth = [myFont advancementForGlyph:(NSGlyph) ' '].width;
Экранный шрифт не предназначен для использования непосредственно вне сервера окон:
Экранные шрифты предназначены только для прямого использования с сервером окон. только с сервером окон. Никогда не используйте их с объектами Application Kit, например в методах setFont:. Внутри Application Kit автоматически использует соответствующий экранный шрифт для шрифта объекта до тех пор, пока представление не поворачивается или масштабируется.