You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Text Kit 2 API在UITextView中实现嵌套编号列表?

实现Text Kit 2嵌套编号列表的正确方式

可以通过UIKit的Text Kit 2实现类似苹果笔记的嵌套编号列表,核心是使用**NSTextListElement**(Text Kit 2专属的列表元素模型)来构建层级化结构,而非依赖旧的NSTextList与NSParagraphStyle的组合——后者在嵌套场景下无法正确处理缩进与层级关联。

核心原理

Text Kit 2通过NSTextContentStorage管理内容,内容由NSTextElement(段落、列表等)组成。嵌套列表需要将NSTextListElement作为父容器,内部嵌套子NSTextListElement或NSTextParagraphElement,以此明确层级关系,系统会自动处理编号和缩进。

完整实现代码

替换原代码中的loadText方法,并调整内容初始化逻辑:

class ViewController: UIViewController {
    var textView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        textView = UITextView(usingTextLayoutManager: true)
        textView.alwaysBounceVertical = true
        textView.keyboardDismissMode = .interactive
        textView.layer.borderColor = UIColor.black.cgColor
        textView.layer.borderWidth = 2

        view.addSubview(textView)

        textView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            textView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            textView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            textView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])

        loadNestedList()
    }

    func loadNestedList() {
        // 1. 创建最外层编号列表(十进制数字)
        let outerList = NSTextListElement(markerFormat: .decimal, startingItemNumber: 1)
        
        // 外层列表项1
        let outerItem1 = NSTextParagraphElement(content: NSAttributedString(string: "外层列表项1"))
        outerList.addElement(outerItem1)
        
        // 2. 创建内层嵌套列表(小写字母)
        let innerList = NSTextListElement(markerFormat: .lowercaseLetter, startingItemNumber: 1)
        
        // 内层列表项
        let innerItem1 = NSTextParagraphElement(content: NSAttributedString(string: "内层列表项1"))
        let innerItem2 = NSTextParagraphElement(content: NSAttributedString(string: "内层列表项2"))
        innerList.addElement(innerItem1)
        innerList.addElement(innerItem2)
        
        // 将内层列表作为外层列表的子项添加
        outerList.addElement(innerList)
        
        // 外层列表项2
        let outerItem2 = NSTextParagraphElement(content: NSAttributedString(string: "外层列表项2"))
        outerList.addElement(outerItem2)
        
        // 3. 将根列表添加到Text Content Storage
        textView.textLayoutManager.textContentStorage.addElement(outerList)
    }
}

关键说明

  • NSTextListElement初始化:通过markerFormat指定编号样式(十进制、字母、罗马数字等),startingItemNumber设置起始编号。
  • 层级嵌套:直接调用addElement(_:)将子列表或段落元素添加到父列表中,系统会自动根据层级计算缩进和编号序列。
  • 替代旧方式:不再需要手动设置firstLineHeadIndent或headIndent,Text Kit 2会基于列表层级自动处理排版。

原代码问题解析

你之前使用NSTextList+NSParagraphStyle的方式属于Text Kit 1的实现逻辑,Text Kit 2虽然兼容基础样式,但嵌套场景下无法识别层级关系,导致缩进不生效。改用NSTextListElement的元素层级模型,才能让系统正确处理嵌套列表的排版和编号。

内容的提问来源于stack exchange,提问作者FE_Tech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:07:11