如何重新布局NSTextView的内容,以便绘制宽度为4个字符的制表符

Lyn*_*son 6 fonts cocoa objective-c appkit

我正在使用NSTextView,我的一个要求是制表符''t'应具有与四个空格相同的宽度.

所以文本内容看起来像这样:

AAAA
    AAAA - 1 tab
    AAAA - 4 spaces
Run Code Online (Sandbox Code Playgroud)

这就是我实现这个目标的方法:

// 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];
}
Run Code Online (Sandbox Code Playgroud)

这允许使用初始文本显示适当的布局,并保持键入属性相同.

问题是最终用户可以更改字体.当发生这种情况时,示例文本会变得不对齐.很像下面的内容:

[smaller font]
AAAA
     AAAA - 1 tab
    AAAA - 4 spaces
Run Code Online (Sandbox Code Playgroud)


[larger font]
AAAA
   AAAA - 1 tab
    AAAA - 4 spaces
Run Code Online (Sandbox Code Playgroud)

我已经尝试调用myTextView的setNeedsDisplay:YES,因为我读到它最终调用NSTextView的setNeedsDisplayInRect:avoidAdditionalLayout,其中的avoidAdditionalLayout参数为NO.这并没有改变任何事情.

当myTextView设置了新的myFont时,我已经尝试调用我的updateMyTextViewTextAttributes调用.这不会改变一件事.

我也试过告诉myTextView的layoutManager来确保myTextView的textContainer的LayoutForTextContainer.没变.

在这一点上,我不确定下一步该尝试什么.有什么建议?

Lyn*_*son 5

Apple 的 Douglas Davidson通过 cocoa-dev@apple.lists.com 电子邮件列表为我提供了找到答案的线索。

\n\n

我通过更新 updateMyTextViewTextAttributes 函数解决了该问题,如下所示:

\n\n
- (void)updateMyTextViewTextAttributes\n{\n\xc2\xa0 \xc2\xa0NSMutableParagraphStyle* paragraphStyle = [[myTextView defaultParagraphStyle] mutableCopy];\n\n\xc2\xa0 \xc2\xa0if (paragraphStyle == nil) {\n\xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];\n\xc2\xa0 \xc2\xa0}\n\n\xc2\xa0 \xc2\xa0float charWidth = [[myFont screenFontWithRenderingMode:NSFontDefaultRenderingMode] advancementForGlyph:(NSGlyph) \' \'].width;\n\xc2\xa0 \xc2\xa0[paragraphStyle setDefaultTabInterval:(charWidth * 4)];\n\xc2\xa0 \xc2\xa0[paragraphStyle setTabStops:[NSArray array]];\n\n\xc2\xa0 \xc2\xa0[myTextView setDefaultParagraphStyle:paragraphStyle];\n\n\xc2\xa0 \xc2\xa0NSMutableDictionary* typingAttributes = [[myTextView typingAttributes] mutableCopy];\n\xc2\xa0 \xc2\xa0[typingAttributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];\n\xc2\xa0 \xc2\xa0[typingAttributes setObject:scriptFont forKey:NSFontAttributeName];\n\xc2\xa0 \xc2\xa0[myTextView setTypingAttributes:typingAttributes];\n\n   /** ADDED CODE BELOW **/\n\xc2\xa0 \xc2\xa0NSRange rangeOfChange = NSMakeRange(0, [[myTextView string] length]);\n\xc2\xa0 \xc2\xa0[myTextView shouldChangeTextInRange:rangeOfChange replacementString:nil];\n\xc2\xa0 \xc2\xa0[[myTextView textStorage] setAttributes:typingAttributes range:rangeOfChange];\n\xc2\xa0 \xc2\xa0[myTextView didChangeText];\n\n   [paragraphStyle release];\n   [typingAttributes release];\n}\n
Run Code Online (Sandbox Code Playgroud)\n