From f0ea1a125133fad92aa07dba96acba9d27fcc92e Mon Sep 17 00:00:00 2001 From: Branden Russell Date: Mon, 16 May 2016 13:48:40 -0600 Subject: [PATCH] Fixed issue where cursor moved incorrectly if next to the bullet/number or at the end of the textview when bullets/numbers were toggled off (#11) * Fixed issue where cursor moved incorrectly if next to the bullet/number or at the end of the textview when bullets/numbers were toggled off * Moved the let next to the other * Removed bad check from if Improved guard * Fixed more selection and cursor placement issues when toggling numbered/bulleted lists * Fixed logic of ranges --- RichTextVC-iOS.podspec | 2 +- src/Classes/NSRange+Extras.swift | 8 +++--- src/Classes/RichTextViewController.swift | 32 ++++++++++-------------- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/RichTextVC-iOS.podspec b/RichTextVC-iOS.podspec index 480d5f3..e240ba5 100644 --- a/RichTextVC-iOS.podspec +++ b/RichTextVC-iOS.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = "RichTextVC-iOS" - s.version = "1.2.1" + s.version = "1.2.2" s.summary = "A Rich Text ViewController for iOS." # This description is used to generate tags and improve search results. diff --git a/src/Classes/NSRange+Extras.swift b/src/Classes/NSRange+Extras.swift index 59e7858..ebd486e 100644 --- a/src/Classes/NSRange+Extras.swift +++ b/src/Classes/NSRange+Extras.swift @@ -16,7 +16,7 @@ extension NSRange { } func containsEntireRange(range: NSRange) -> Bool { - return (location < range.location) && ((range.location - location) + range.length <= length) + return containsBeginningOfRange(range) && containsEndOfRange(range) } func containedInRange(range: NSRange) -> Bool { @@ -24,15 +24,15 @@ extension NSRange { } func containsEndOfRange(range: NSRange) -> Bool { - return location < range.endLocation && range.endLocation < endLocation + return length > 0 && location <= range.endLocation && range.endLocation < endLocation } func containsBeginningOfRange(range: NSRange) -> Bool { - return range.location < endLocation && endLocation < range.endLocation + return length > 0 && location <= range.location && endLocation >= range.location } func comesBeforeRange(range: NSRange) -> Bool { - return endLocation < range.location + return endLocation <= range.location } func comesAfterRange(range: NSRange) -> Bool { diff --git a/src/Classes/RichTextViewController.swift b/src/Classes/RichTextViewController.swift index 5e99a36..f1802dc 100644 --- a/src/Classes/RichTextViewController.swift +++ b/src/Classes/RichTextViewController.swift @@ -62,22 +62,19 @@ public class RichTextViewController: UIViewController { /// - parameter toTextView: The `UITextView` to remove the text from. private func removeTextFromRange(range: NSRange, fromTextView textView: UITextView) { let substringLength = (textView.text as NSString).substringWithRange(range).length - + let initialRange = textView.selectedRange + textView.textStorage.beginEditing() textView.textStorage.replaceCharactersInRange(range, withAttributedString: NSAttributedString(string: "")) textView.textStorage.endEditing() if range.comesBeforeRange(textView.selectedRange) { - textView.selectedRange.location -= substringLength + textView.selectedRange.location -= (substringLength - (initialRange.location - textView.selectedRange.location)) + textView.selectedRange.length = initialRange.length } else if range.containedInRange(textView.selectedRange) { - textView.selectedRange.length -= substringLength - } else if range.containsBeginningOfRange(textView.selectedRange) { - let inSelectionRemoved = textView.selectedRange.location - range.location - let outSelectionRemoved = range.length - inSelectionRemoved - textView.selectedRange.location -= outSelectionRemoved - textView.selectedRange.length -= inSelectionRemoved - } else if range.containsEndOfRange(textView.selectedRange) { - textView.selectedRange.length -= textView.selectedRange.endLocation - range.location + textView.selectedRange.length -= (substringLength - (initialRange.length - textView.selectedRange.length)) + } else if range.location == textView.selectedRange.location && range.length == textView.selectedRange.length { + textView.selectedRange.length = 0 } textViewDidChangeSelection(textView) @@ -174,8 +171,8 @@ public class RichTextViewController: UIViewController { var index = textView.selectedRange.location while index < textView.text.length { - guard let newLineIndex = textView.text.nextIndexOfSubstring("\n", fromIndex: index) where - newLineIndex < textView.selectedRange.endLocation else { break } + guard let newLineIndex = textView.text.nextIndexOfSubstring("\n", fromIndex: index) where newLineIndex < textView.selectedRange.endLocation else { break } + addText("\(newNumber)\(RichTextViewController.numberedListTrailer)", toTextView: textView, atIndex: newLineIndex + 1) newNumber += 1 index = newLineIndex + 1 @@ -212,7 +209,6 @@ public class RichTextViewController: UIViewController { guard let numberedTrailerIndex = string.nextIndexOfSubstring(RichTextViewController.numberedListTrailer, fromIndex: index) else { return nil } var newLineIndex = string.previousIndexOfSubstring("\n", fromIndex: numberedTrailerIndex) ?? -1 - if newLineIndex >= -1 { newLineIndex += 1 } @@ -496,12 +492,10 @@ public class RichTextViewController: UIViewController { } private func removeFormattingFromListLeadsInRange(range: NSRange) { - guard let listHeadRegex = try? NSRegularExpression(pattern: "^(([0-9]+\\.\\u00A0)|(\\u2022\\u00A0)).*$", options: .AnchorsMatchLines), - regularFont = regularFont where - range.length > 0 - else { - print("Failed to remove formatting") - return + guard let regularFont = regularFont else { return } + guard range.length > 0, let listHeadRegex = try? NSRegularExpression(pattern: "^(([0-9]+\\.\\u00A0)|(\\u2022\\u00A0)).*$", options: .AnchorsMatchLines) else { + print("Failed to remove formatting") + return } listHeadRegex.matchesInString(textView.text, options: [], range: range).forEach { match in