NSAttributedString中类似于水平分隔符<hr>的分隔符

5

我该如何创建一个NSAttributedString对象,它基本上是一个水平分隔线,就像HTML的<hr>标签一样?

我尝试了以下代码:

NSAttributedString *hr = [[NSAttributedString alloc] initWithHTML:
  [NSData
    dataWithBytes:"<html><body><hr>hi</body></html>"
    length:strlen("<html><body><hr>hi</body></html>")]
  documentAttributes:NULL];

然而,<hr> 标签没有出现。不过在我的视图中添加这个字符串是可以的,因为我可以看到 hi
3个回答

13

这是一个相当古老的问题,但我认为值得更全面地回答。

获得水平分隔线的简单方法是设置一个具有制表位的段落,其长度为所需规则的长度,并将其对齐设置为中心。 然后将文本设置为U+00A0 U+0009 U+00A0,并在文本上设置删除线属性。 制表位的位置确定了规则的长度。 这具有使用复制和粘贴以及其他使用文本系统的程序的显着优点。

如果您想要(例如)随文本扩展的水平规则,则可以使用具有自定义单元的NSTextAttachment的方式也会起作用。 单元格传递了行片段矩形,并且可以根据需要设置自己的框架。 顺便说一下,您不必为NSTextAttachment使用图像; 您的单元格可以进行自定义绘制。 不过,您将遇到的问题是,复制和粘贴将根据附件内容设置单元格类型(这是有道理的,因为您的自定义单元格在其他应用程序中不可用)。 您可以采用混合方法,将图像设置为附件,同时在应用程序中进行自定义渲染; 黄金版本可以使用PNG附件中的自定义标记来指示应自定义呈现。

您还可以尝试使用NSTextTable绘制规则,但我没有尝试过这种方法,不过我认为它很容易做到。

最后,您可以选择执行Kevin建议的操作-使用NSLayoutManager计算适当的位置并自己进行渲染。


阿拉斯泰尔,我认为我喜欢这种方法,但您有一些能够澄清它的代码吗? - Steven Hovater
感谢您的努力...第一个解决方案非常好(对我的情况需要进行微小的更改) - Yitzchak

2

我尝试遵循@alasair指令的第一种方法,并成功地在Swift中使用了这个:

let hr = NSAttributedString(string: "\n\r\u{00A0} \u{0009} \u{00A0}\n\n", attributes: [.strikethroughStyle: NSUnderlineStyle.single.rawValue, .strikethroughColor: UIColor.gray])

这将呈现出横穿整个屏幕宽度的以下行:

水平线


1
我复制/粘贴了这段代码,它在深色和浅色配色方案中都运行得非常好。 - Adam

1
你需要自己绘制它。"<hr>"不是文本,也不是修改文本的属性。因此,NSAttributedString无法表示它,Cocoa文本系统或CoreText也没有绘制它的功能。

哦,如果我不能使用 NSAttributedString,那么我该如何将 <hr> 插入到 NSTextView 中呢? - houbysoft
@houbysoft:我认为你仍然需要自己绘制它。在文本渲染中加入一些空间,计算出位置,并在文本视图的该部分可见时绘制它。 - Lily Ballard
真的没有更好(/更容易)的方法吗?例如,我知道您可以通过NSTextAttachment将图像添加到NSAttributedString中,也许我可以使用它? - houbysoft
@houbysoft:我想你可以尝试动态创建一个图像,在其中绘制<hr>,然后附加它,但是如果您的文本字段的宽度发生变化,那么您就会遇到麻烦。更不用说你仍然要自己画这个可恶的东西了。 - Lily Ballard
好的...我可能会放弃使用<hr>了。它并不是必要的,所以我不能为此花费太多时间,但这将是一个很好的功能。 - houbysoft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接