6

NSTextView[1] で HTML のサブセットを編集していて、<hr> タグをシミュレートしたいと考えています。

それを行う方法は NSTextAttachment とカスタム NSTextAttachmentCell を使用することであり、添付ファイルとセルを挿入するためのコードがすべて記述されていることがわかりました。問題は、セルの下に膨大な量の空白があることです。

このスペースはセル自体の一部ではありません。セルの領域全体を赤く塗ると、ちょうどいいサイズになりますが、テキスト ビューでは、次のテキスト行が赤のはるか下に表示されます。量は、セルのにあるテキストの量に依存するようです。残念ながら、私は <hr> タグが重要な長いドキュメントを扱っており、これがアプリに大きな問題を引き起こしています。

一体何が起こっているのですか?

私のセルサブクラスのお金の部分:

- (NSRect)cellFrameForTextContainer:(NSTextContainer *)textContainer 
               proposedLineFragment:(NSRect)lineFrag glyphPosition:(NSPoint)position 
                     characterIndex:(NSUInteger)charIndex {
    lineFrag.size.width = textContainer.containerSize.width;

    lineFrag.size.height = topMargin + TsStyleBaseFontSize * 
        heightFontSizeMultiplier + bottomMargin;

    return lineFrag;
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 
       characterIndex:(NSUInteger)charIndex 
        layoutManager:(NSLayoutManager *)layoutManager {
    NSRect frame = cellFrame;
    frame.size.height -= bottomMargin;

    frame.size.height -= topMargin;
    frame.origin.y += topMargin;

    frame.size.width *= widthPercentage;
    frame.origin.x += (cellFrame.size.width - frame.size.width)/2;

    [color set];
    NSRectFill(frame);
}

[1] isEditable を設定して WebView を試してみましたが、生成されたマークアップは使用できないほど汚れていました。特に、テキストを <p> タグで適切にラップする方法が見つかりませんでした。


水平線の添付ファイルを挿入するコードに対する Rob Keniger の要求に答えるには、次のようにします。

- (void)insertHorizontalRule:(id)sender {
    NSAttributedString * rule = [TsPage newHorizontalRuleAttributedStringWithStylebook:self.book.stylebook];

    NSUInteger loc = self.textView.rangeForUserTextChange.location;

    if(loc == NSNotFound) {
        NSBeep();
        return;
    }

    if(loc > 0 && [self.textView.textStorage.string characterAtIndex:loc - 1] != '\n') {
        NSMutableAttributedString * workspace = rule.mutableCopy;
        [workspace.mutableString insertString:@"\n" atIndex:0];
        rule = workspace;
    }

    if([self.textView shouldChangeTextInRange:self.textView.rangeForUserTextChange replacementString:rule.string]) {
        [self.textView.textStorage beginEditing];
        [self.textView.textStorage replaceCharactersInRange:self.textView.rangeForUserTextChange withAttributedString:rule];
        [self.textView.textStorage endEditing];
        [self.textView didChangeText];
    }

    [self.textView scrollRangeToVisible:self.textView.rangeForUserTextChange];

    [self reloadPreview:sender];
}

添付文字列を構築する TsPage のメソッド:

+ (NSAttributedString *)newHorizontalRuleAttributedStringWithStylebook:(TsStylebook*)stylebook {
    TsHorizontalRuleCell * cell = [[TsHorizontalRuleCell alloc] initTextCell:@"—"];
    cell.widthPercentage = 0.33;
    cell.heightFontSizeMultiplier = 0.25;
    cell.topMargin = 12.0;
    cell.bottomMargin = 12.0;
    cell.color = [NSColor blackColor];

    NSTextAttachment * attachment = [[NSTextAttachment alloc] initWithFileWrapper:nil];
    attachment.attachmentCell = cell;
    cell.attachment = attachment;

    NSAttributedString * attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];

    NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:@""];
    [str appendAttributedString:attachmentString];
    [str.mutableString appendString:@"\n"];

    return str;
}
4

1 に答える 1

5

セル クラスのメソッドを変更して、セルのフレームの原点cellFrameForTextContainer:proposedLineFragment:glyphPosition:を返すようにしてください。NSZeroPoint

(なぜこれが機能するのかわかりませんが、質問者と私はライブデバッグを行っており、実際に機能しています。)


質問者による追加:返される rect は「フレーム」として記述されていますが、その原点は、ドキュメントの先頭ではなく、それが含まれる行に関連しているようです。したがって、origin.y同じ行に戻したい場合は、戻り値の値をゼロに設定する必要があります。

(origin.x一方、値lineFrag.origin.x行内のセルの位置を参照するため、セルの水平方向の位置を変更したい場合を除き、同じにする必要があります。)

于 2012-01-04T06:39:23.260 に答える