【问题标题】:Get the range of a paragraph NSAttributedString获取段落的范围 NSAttributedString
【发布时间】: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

但是,这将在同一范围内合并具有相同段落样式的连续段落。

  1. 用户创建了三个左对齐的段落
  2. 用户想把中间的改成右对齐
  3. 他们应该能够 a) 选择段落的任何部分 b) 将光标置于段落中的任意位置(选择长度为 0)以达到相同的结果(影响整个段落
  4. 当前使用 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


【解决方案1】:

聚会有点晚了,但希望这会有所帮助。

我解决这个问题的方法是保存选定的范围,从我的 NSAttributedString 中提取一个 NSString,然后调用 NSString 的段落范围。一旦有了段落范围,就可以随意枚举!

//0: SAVE RANGE

let rangeOfNote = yourTextView.selectedRange


//1: CONVERT NSATTRIBUTEDSTRING TO NSSTRING

let composeText = yourTextView.attributedText.string as NSString


//2: CALL NSSTRING'S PARAGRAPH RANGE (for: NSRange)

let paragraphRange = composeText.paragraphRange(for: rangeOfNote)


//3: CHECK CORRECT
    
print(composeText.substring(with: paragraphRange), paragraphRange)

//4: Use range in enumerate attributes.

yourTextView.attributedText.enumerateAttributes(in: paragraphRange, ...)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-30
    相关资源
    最近更新 更多