如何在文本视图中实现水平线?

How to implement a horizontal rule in a text view?

假设我有一个 NSTextView(或 iOS 上的 UITextView)并且我希望用户能够插入水平分隔规则,例如 HTML <hr> 标签或这个东西:


实现这个的最佳方法是什么?

Apple 的文档对此非常重视。到目前为止,我有两个想法:

  1. 为每个规则插入一个 NSTextAttachment 并让布局管理器以某种方式绘制它。

  2. 使用禁用滚动的多个文本视图,而不是单个文本视图,将它们放在堆栈视图中,在它们之间添加分隔视图,然后将堆栈视图放在滚动视图中。

这两种方法对我来说似乎都有点错误或不够优雅,因为:

  1. 从文档来看,文本附件听起来像是首先用于附加文件。水平线不是文件。

  2. 如果我使用多个文本视图,我可能会失去一些 NSTextView 固有的性能调整,因为所有文本视图都需要加载并准备好显示,无论在哪里用户已滚动。此外,多文本视图方法会阻止用户选择整个文本,这是我的应用程序的要求。

有更好的主意吗?

我记得几年前尝试过这样做。使用 NSTextAttachment 是对我有用的方法。我为 Mike Ferris 添加了 this conversation 书签,以帮助我记住如何操作。我没有代码了,但它非常简单。我子类 NSTextAttachmentCell 符合 NSTextAttachmentCellProtocol。您重写 cellFrame(for textContainer: NSTextContainer, proposedLineFragment lineFrag: NSRect, glyphPosition position: NSPoint, characterIndex charIndex: Int) ,它使您可以访问其可以提供其宽度的容器,并且它具有行片段,该行片段为您提供分隔符上方文本的 y 位置(加上您想要的任何填充)。然后只需覆盖 draw(withFrame cellFrame: NSRect, in controlView: NSView?) 方法并绘制分隔线即可。

至于负载 NSData,您可以用它做任何事情。也许你包括线的宽度,它的填充,颜色等?使用 NSTextAttachment 的好处是它像 <hr> 标签一样嵌入文本本身。