我试图弄清楚如何使用 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,注意标记周围的间距
这是我的 textView,注意标记周围较大的间距,在下面突出显示的过程之后,将恢复为“默认”文本编辑间距...
我希望能从中得到三件事:
\t
围绕标记使其工作。 最佳答案
注意事项:我也对此感到困惑,这是我尝试实现您在上面链接的评论中的信息。
我正在处理的一个项目中遇到了类似的问题。发现 textView 正在更改 tabStops 数组 ( paragraphStyle.tabStops
) 从默认值,当用户从嵌套列表移回主列表时,如您在屏幕截图中所展示的。要验证,请尝试打印以控制台显示包含“列表项 1”的段落与包含“列表继续”的段落的第一个 tabStop ( paragraphStyle.tabStops.first.location
) 的位置。
我提出的并且仍在迭代的幼稚解决方案是检查编辑过的段落是否具有:
如果上述两个条件都成立,我会将编辑过的段落的 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/