NSTextAttachmentCell高一英里

Bre*_*don 6 cocoa objective-c nstextview nstextattachment

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

[1]我试图与isEditable集的web视图和它产生的标记是unusably脏尤其,我无法找到一种方法来包装<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];
}
Run Code Online (Sandbox Code Playgroud)

和构造附件字符串的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;
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*sey 5

尝试更改单元格类的cellFrameForTextContainer:proposedLineFragment:glyphPosition:方法以返回NSZeroPoint单元格框架的原点.

(我不知道为什么这应该有效,但提问者和我一直在实时调试它,实际上它确实如此.)


提问者添加:看起来,即使返回的rect被描述为"框架",它的原点是相对于它所在的行,而不是文档的顶部.因此,origin.y如果您希望将返回值的值放在同一行,则应将其值设置为零.

(origin.x另一方面,该值确实指的是单元格在行中的位置,因此lineFrag.origin.x除非您想要更改单元格的水平位置,否则它应该相同.)