Reputation: 704
I would like to be able to get the range(s) of the paragraph(s) overlapping with the textView.selectedRange.
My goal is to change the alignment of the whole paragraph where the selection is.
I have tried the following but the ranges provided by enumerate attribute seem to all be of length 1, making my intersection check useless.
Is there a way to get a list of continuous ranges with the same paragraph style?
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)
}
}
}
Many thanks
Thanks to @Larme, having no options does indeed get a continuous range:
editor.attributedText.enumerateAttribute(.paragraphStyle, in: contentRange, options: []) { (paragraphStyle, range, _) in
However, this will combine consecutive paragraphs with the same paragraph style in the same range.
i.e.
enumarateAttribute
will return a range grouping all three paragraphs together (as they all have the same paragraphStyle) and apply the new alignment to all of them.The enumerateAttribute
doesn't really get the range of a single paragraph it will return a consecutive range for all consecutive paragraphs with the same paragraphStyle
Is there another way to get the range of the paragraph corresponding to the selectedRange?
Upvotes: 1
Views: 1529
Reputation: 136
A bit late to the party, but hopefully this helps.
The way I approached this problem was by saving the selected range, pulling an NSString from my NSAttributedString, then calling NSString's paragraphRange. Once you have the paragraph range, then you can enumerate however you'd like!
//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, ...)
Upvotes: 1