我正在编辑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;
}
答案 0 :(得分:5)
尝试更改单元格类的cellFrameForTextContainer:proposedLineFragment:glyphPosition:
方法,以返回单元格框架原点的NSZeroPoint
。
(我不知道为什么这应该有用,但提问者和我一直在现场调试它,它实际上是。)
由提问者添加:看起来,即使返回的rect被描述为“框架”,其原点也是相对于它所在的行,而不是文档的顶部。因此,如果您希望将返回值origin.y
值放在同一行,则应将其设置为零。
(另一方面,origin.x
值 指的是单元格在行中的位置,因此它应与lineFrag.origin.x
相同,除非您想要更改单元格的水平位置。)