【问题标题】:NSTextAttachmentCell is a mile highNSTextAttachmentCell 高一英里
【发布时间】:2011-12-19 08:42:36
【问题描述】:

我正在编辑一个 NSTextView[1] 中的 HTML 子集,我想模拟一个


标签。

我已经想出实现它的方法是使用 NSTextAttachment 和自定义 NSTextAttachmentCell,并编写所有代码来插入附件和单元格。问题是,单元格下方有大量空白区域。

这个空间不是单元格本身的一部分——如果我将单元格的整个区域涂成红色,它的大小正好合适,但文本视图将下一行文本放在红色下方很远的地方。数量似乎取决于单元格上方有多少文本;不幸的是,我正在处理


标签至关重要的长文档,这会导致应用出现重大问题。

这到底是怎么回事?

我的细胞子类的钱部分:

- (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,但它生成的标记非常脏——特别是,我找不到在

标记中很好地包装文本的方法。


回答 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;
}

【问题讨论】:

  • 您能否发布代码以显示您如何在NSTextView 中插入文本附件?
  • Rob,我已经添加了你想看的代码。感谢您查看此内容!

标签: objective-c cocoa nstextview nstextattachment


【解决方案1】:

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

(我不知道为什么这会起作用,但提问者和我一直在对其进行实时调试,并且确实如此。)


由提问者补充:看起来,即使返回的矩形被描述为“框架”,它的原点也是相对于它所在的行,而不是文档的顶部。因此,如果您希望返回值的origin.y 值位于同一行,则应将其设置为零。

(另一方面,origin.x 的值,确实指的是单元格在行中的位置,所以它应该与 lineFrag.origin.x 相同,除非你想改变单元格的水平位置。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-17
    • 2017-06-12
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-24
    相关资源
    最近更新 更多