【发布时间】:2021-03-02 16:05:16
【问题描述】:
我希望能够获得与 textView.selectedRange 重叠的段落范围。
我的目标是改变整个段落的对齐方式。
我尝试了以下方法,但 enumerate 属性提供的范围似乎都是长度为 1,使我的交集检查无用。
有没有办法获取具有相同段落样式的连续范围列表?
var alignment: NSTextAlignment
let contentRange = NSRange(location: 0, length: editor.contentLength)
editor.attributedText.enumerateAttribute(.paragraphStyle, in: contentRange, options: .longestEffectiveRangeNotRequired) { (paragraphStyle, range, _) in
//Check if attribute range contains cursor
if NSIntersectionRange(range, editor.selectedRange).length > 0 {
print(range)
if let paragraphStyle = paragraphStyle as? NSParagraphStyle {
let newStyle: NSMutableParagraphStyle = paragraphStyle.mutableParagraphStyle
newStyle.alignment = alignment
editor.addAttribute(.paragraphStyle, value: newStyle, at: range)
}
}
}
非常感谢
编辑
感谢@Larme,没有选项确实得到了一个连续的范围:
editor.attributedText.enumerateAttribute(.paragraphStyle, in: contentRange, options: []) { (paragraphStyle, range, _) in
但是,这将在同一范围内合并具有相同段落样式的连续段落。
即
- 用户创建了三个左对齐的段落
- 用户想把中间的改成右对齐
- 他们应该能够 a) 选择段落的任何部分 b) 将光标置于段落中的任意位置(选择长度为 0)以达到相同的结果(影响整个段落)
- 当前使用
enumarateAttribute的检查将返回一个将所有三个段落组合在一起的范围(因为它们都具有相同的段落样式)并将新的对齐方式应用于所有段落。
enumerateAttribute 并没有真正获得单个段落的范围,它会为所有具有相同段落样式的连续段落返回一个连续范围
还有其他方法可以获取选定范围对应的段落范围吗?
【问题讨论】:
-
longestEffectiveRangeNotRequired不使用任何选项。想象一下,你的第一个字符是字体效果 1 和段落效果 2,第二个字符是字体效果 3 和段落效果 2。使用您的方法,您将获得两个命中,每个字母一个,而没有选项,它只会为两个字母找到一种段落样式。 -
好像值变了,但是看命名,还是一样的逻辑:stackoverflow.com/questions/32297969/…
-
@Larme 谢谢。这正是我一直在寻找的,但是我的逻辑有缺陷。这将在同一范围内封装具有相同段落样式的所有段落。因此,即使光标位置不在段落中,也将对齐应用于所有这些。我必须想出一个更好的方法来检测光标的段落。有什么想法吗?
-
in: contentRange,而不是使用editor.selectedRange;) 然后,而不是editor.addAttribute(.paragraphStyle, value: newStyle, at: range),使用``editor.addAttribute(.paragraphStyle, value: newStyle, at: NSIntersectionRange(range, editor. selectedRange), that should do the trick, no? -
好的。我会说,从 selectedRange 中,您必须找到自己的段落,寻找“\n”:上一个和下一个。
标签: swift uikit uitextview nsattributedstring