swift - NSTextList 格式

标签 swift macos appkit nstextview

我试图弄清楚如何使用 NSTextList,但除了 this SO question 之外,在网上几乎没有找到有用的信息。和 the comment in this blog .
使用这个我已经能够创建一个粗略的例子来弄清楚:

    let textView = NSTextView()
    
    //Create NSTextList
    let list = NSTextList(markerFormat: .decimal, options: 0)
    list.startingItemNumber = 1
    
    //Create NSParagraphStyle with text list
    let paragraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
    paragraphStyle.textLists = [list]
    
    let attributes = [NSAttributedString.Key.paragraphStyle : paragraphStyle]
    
    //Add attributes to list block
    let nsmutableAttributedString = NSMutableAttributedString(string: "\t\(list.marker(forItemNumber: 1))\tList Item 1 ", attributes: attributes)
    
    textView.textStorage?.setAttributedString(nsmutableAttributedString)
    
    return textView
这很有效,当应用程序运行时,按 enter创建一个新的格式正确的行并按 tab正确缩进列表项。
一切顺利... 然而 ,标记周围的间距似乎不正确,并不能反射(reflect)您在 TextEdit 中得到的内容。
这是 TextEdit,注意标记周围的间距
exhibit a
这是我的 textView,注意标记周围较大的间距,在下面突出显示的过程之后,将恢复为“默认”文本编辑间距...
enter image description here
我希望能从中得到三件事:
  • 我是否以任何方式做错了?我很确定我必须使用 \t围绕标记使其工作。
  • 关于如何实现 Apple 在其所有文本编辑应用程序(笔记、textedit 等)中实现的标记周围默认间距的任何想法
  • NSTextList 的任何一般提示。那里没有太多东西,所以如果有人可以分享他们的知识,那将不胜感激。
  • 最佳答案

    注意事项:我也对此感到困惑,这是我尝试实现您在上面链接的评论中的信息。
    我正在处理的一个项目中遇到了类似的问题。发现 textView 正在更改 tabStops 数组 ( paragraphStyle.tabStops ) 从默认值,当用户从嵌套列表移回主列表时,如您在屏幕截图中所展示的。要验证,请尝试打印以控制台显示包含“列表项 1”的段落与包含“列表继续”的段落的第一个 tabStop ( paragraphStyle.tabStops.first.location ) 的位置。
    我提出的并且仍在迭代的幼稚解决方案是检查编辑过的段落是否具有:

  • 文字列表
  • 一个 tabStop,其位置在默认的最左侧 tabStop 位置的左侧。

  • 如果上述两个条件都成立,我会将编辑过的段落的 tabStops 重置为默认值。
    我目前正在研究以下功能的变体,专门用于解决您所概述的问题。我调用 didProcessEditing NSTextStorage 委托(delegate)方法中的函数,传入 textStorage 和editedRange。
        func handleTabStopsIssue(textStorage: NSTextStorage, editedRange: NSRange) {
            //Determine range of the edited paragraph (this is encompases the editedRange).
            let rangeOfEditedParagraph = textStorage.mutableString.paragraphRange(for: editedRange)
            //Retrieve the edited paragraph as attributed string
            let editedParagraph = textStorage.attributedSubstring(from: rangeOfEditedParagraph)
            //Enumerate the paragraphStyle attribute in the inputted paragraph NSAttributedString
            editedParagraph.enumerateAttribute(.paragraphStyle, in: NSRange(location: 0, length: editedParagraph.length), options: .longestEffectiveRangeNotRequired, using: {atts, subrange, _ in
                //Determine whether or not paragraph contains a textList
                guard let parStyle = atts as? NSParagraphStyle else { return }
                let parHasTextList = !parStyle.textLists.isEmpty
                
                //Retrieve the default tabStops to compare their location with inputted paragraph tabStop locations
                let defaultTabStops = NSParagraphStyle.default.tabStops
                guard let firstDefaultTabStop = defaultTabStops.first else { return }
                guard let inputParFirstTabStop = parStyle.tabStops.first else { return }
                print("firstDefaultTabStop \(firstDefaultTabStop) of location \(firstDefaultTabStop.location)")
                print("currentParTabStop \(inputParFirstTabStop) of location \(inputParFirstTabStop.location)")
                
                //If parStyle has textList, and its first tab stop is located to the left of the default tab stops...
                if (inputParFirstTabStop.location < firstDefaultTabStop.location) && parHasTextList {
                    print("🔥 Resetting tabstops!")
                    //Set the inputted paragraph's tab stops, to default
                    let newParStyle = parStyle.mutableCopy() as! NSMutableParagraphStyle
                    newParStyle.tabStops = defaultTabStops
                    textView.textStorage?.addAttribute(.paragraphStyle, value: newParStyle, range: rangeOfEditedParagraph)
                }
            })
        }
    
    我已经在 gitHub 上传了一个工作演示:https://github.com/MQumairi/TextKit-List/blob/main/List%20Problems/ViewController.swift
    将清晰度优先于效率,代码可以更高效。只是想表明我的逻辑。
    这仍在进行中,因为上述方法不适用于阿拉伯语等从右到左的语言。需要处理这种边缘情况。但这是一个起点,希望可以帮助其他人坚持这个问题。

    关于swift - NSTextList 格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66714650/

    相关文章:

    ios - Realm 列表与 LinkingObjects 性能

    ios - 添加 Watchkit 扩展并让 iPhone 完成工作

    ios - 2 行文本 UIButton

    iphone - iOS 与 MAC OS 的兼容性问题

    ios - 苹果的证书是什么?

    c++ - 如何在 macOS 上为 Qt 窗口使用 Objective-C 变量和方法?

    ios - 这里映射 iOS SDK : Rotate the marker in Here maps

    macos - 如何使用 Excel for Mac 2011 将工作表保存为 UTF-8 格式的 CSV 文件?

    Cocoa 自定义系统上下文菜单

    macos - 如何为 NSCollectionView 的 "Overshoot"背景着色