7

NSTextViewを使用していますが、要件の1つは、タブ文字'\t'の幅が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

myTextViewのsetNeedsDisplay:YESを呼び出してみましたが、これは、avoidAdditionalLayoutパラメーターにNOを指定してNSTextViewのsetNeedsDisplayInRect:avoidAdditionalLayoutを呼び出すことになります。これは何も変わりませんでした。

myTextViewに新しいmyFontが設定されているときに、updateMyTextViewTextAttributes呼び出しを呼び出してみました。それは物事を変えません。

また、myTextViewのlayoutManagerに、myTextViewのtextContainerのLayoutForTextContainerを確保するように指示してみました。変化なし。

この時点で、次に何を試すべきかわかりません。助言がありますか?

4

2 に答える 2

4

Apple の Douglas Davidson は、cocoa-dev@apple.lists.com のメーリング リストを介して、答えにたどり着く手がかりを提供してくれました。

次のように 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];
}
于 2010-02-19T18:16:46.887 に答える
1

advancementForGlyph:画面フォントではなく、フォント上で直接スペースの進歩を計算しようとしましたか?

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

スクリーンフォントは、ウィンドウサーバーの外部で直接使用するためのものではありません。

スクリーンフォントは、ウィンドウサーバーでのみ直接使用するためのものです。setFont:メソッドなどのApplicationKitオブジェクトと一緒に使用しないでください。内部的には、アプリケーションキットは、ビューが回転または拡大縮小されていない限り、フォントオブジェクトに対応する画面フォントを自動的に使用します。

于 2010-02-18T08:29:54.727 に答える