如何可靠地检测 NSParagraphStyle 是否认为它是一个列表(的一部分)?

How to reliably detect if NSParagraphStyle thinks it is (part of) a list?

我有一些真正被诅咒的代码,它通过检查 style.description 字符串来检测 NSParagraphStyle 实例是否具有非空“列表”:

attributedString.enumerateAttribute(
    .paragraphStyle, 
    in: fullLength,
    options: .longestEffectiveRangeNotRequired
) { style, range, _ in
    guard let style = style as? NSParagraphStyle else { return }
    if let maybeList = style.description
            .components(separatedBy: "Lists (\n")
            .dropFirst().first,
        !maybeList.starts(with: ")") {
   // we have (part of) a list-item! ... but I feel dirty
}

这适用于像这样的描述字符串:

Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 36, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (
    11L,
    36N
), DefaultTabInterval 36, Blocks (null), Lists (
    "NSTextList 0x6000014408d0 format <{disc}>"
), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (
) ListIntentOrdinal 0 CodeBlockIntentLanguageHint '(null)' 

但这不是我所说的“稳健”:-)文档确实提到了 textLists 属性,但它只在 AppKit (macOS) 中,而我正在构建对于 UIKit (iOS)。它看起来更像是 那里 不过,在幕后,根据描述字符串判断。那么:我可以“合法地”使用它吗?

在撰写本文时,没有 public API 来创建带有 (NS)AttributedString 的列表。要制作自己的列表,您需要使用 headIndent 之类的技巧,如 this article 所示。

但是,NSParagraphStyle 仍然响应 textLists 选择器(至少目前如此),即使它没有将 textLists 公开为 属性,如应用套件。

因此,您在技术上可以做到:

extension NSParagraphStyle {
    var containsLists: Bool {
        let sel: Selector = "textLists"
        guard self.responds(to: sel) else { return false }
        guard let list = self.perform(sel).takeUnretainedValue() as? [Any] else { return false }
        return !list.isEmpty
    }
}

但我不确定这是否会使您的应用程序被 App Store 拒绝。