NSTextList 格式

问题描述

我正在尝试弄清楚如何使用 NSTextList,但除了 this SO questionthe comment in this blog 之外,在网上几乎没有找到有用的信息。

使用这个我已经能够创建一个粗略的例子来弄清楚:

var request = (HttpWebRequest)WebRequest.Create("https://localhost:44351/mycontroller");
var postData = "n=42&s=25";
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
request.Headers["X‐test"] = "884436999";

这很有效,当应用程序运行时,按 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 会正确缩进列表项。

一切都很好...但是标记周围的间距似乎不正确,并不能反映您在 TextEdit 中得到的内容

这是 TextEdit,注意标记周围的间距

exhibit a

这是我的 textView,注意标记周围较大的间距,在下面突出显示的过程之后,它恢复到“认”文本编辑间距...

enter image description here

我希望能从中得到三件事:

  1. 我做错了吗?我很确定我必须在标记周围使用 tab 才能使其正常工作。
  2. 关于如何实现 Apple 在其所有文本编辑应用(notes、textedit 等)中实现的标记周围认间距的任何想法
  3. NSTextList 的任何一般提示。那里没有太多东西,所以如果有人能分享他们的知识,我们将不胜感激。

解决方法

注意事项:我也对此感到困惑,这是我尝试实施您上面链接的评论中的信息。

我正在处理的一个项目中遇到了类似的问题。发现当用户从嵌套列表移回主列表时,textView 正在更改 tabStops 数组 (paragraphStyle.tabStops) 的默认值,如您在屏幕截图中所示。要进行验证,请尝试打印以控制台显示包含“列表项 1”的段落与包含“列表继续”的段落的第一个 tabStop (paragraphStyle.tabStops.first.location) 的位置。

我提出并仍在迭代的幼稚解决方案是检查编辑的段落是否有:

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

如果上述两个条件都成立,我将编辑段落的 tabStops 重置为默认值。

我目前正在研究以下函数的变体,专门用于解决您所概述的问题。我调用了 didProcessEditing NSTextStorage 委托方法中的函数,传入了 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

优先考虑清晰度而不是效率,代码可以更高效。只是想展示我的逻辑。

这仍在进行中,因为上述方法不适用于阿拉伯语等从右到左的语言。需要处理这种边缘情况。但这是一个起点,希望可以帮助其他人解决这个问题。