Skip to content

Commit

Permalink
Replace Range<String.Index> with NSRange
Browse files Browse the repository at this point in the history
  • Loading branch information
wiruzx committed Jun 21, 2020
1 parent 0752504 commit 20c3357
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 47 deletions.
25 changes: 12 additions & 13 deletions HyperLabel/HyperLabelPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public final class HyperLabelPresenter<TextView: UIView> where TextView: TextCon

// MARK: - Private properties

private var linkRegistry = RangeMap<String.Index, LinkItem>()
private var linkRegistry = RangeMap<LinkItem>()
private let layoutInfoProvider = TextLayoutInfoProvider()
private var textStyler = HyperLabelTextStyler()

Expand All @@ -67,7 +67,7 @@ public final class HyperLabelPresenter<TextView: UIView> where TextView: TextCon
set { self.textStyler.linkAttributes = newValue }
}

public func addLink(addLinkWithRange range: Range<String.Index>,
public func addLink(addLinkWithRange range: NSRange,
accessibilityIdentifier: String?,
withHandler handler: @escaping Handler) {
guard let textView = self.textView else {
Expand Down Expand Up @@ -155,7 +155,7 @@ public final class HyperLabelPresenter<TextView: UIView> where TextView: TextCon
return result
}

private func rect(forRange range: Range<String.Index>) -> CGRect {
private func rect(forRange range: NSRange) -> CGRect {
guard let view = self.textView else {
assertionFailure("textView is nil")
return .zero
Expand All @@ -182,21 +182,20 @@ public final class HyperLabelPresenter<TextView: UIView> where TextView: TextCon
return self.linkRegistry.value(at: index)?.handler
}

private func makeAccessibilityElement(range: Range<String.Index>,
private func makeAccessibilityElement(range: NSRange,
accessibilityIdentifier: String) -> LinkAccessibilityElement? {
guard let container = self.textView else {
assertionFailure("textView is nil")
return nil
}
guard let string = container.attributedText?.string else { return nil }
guard let data = string.data(using: .utf16) else { return nil }
guard let reconstructed = String(bytes: data, encoding: .utf16) else { return nil }
let original = reconstructed + ""
let value = String(original[range])
return LinkAccessibilityElement(accessibilityContainer: container,
range: range,
value: value,
identfier: accessibilityIdentifier)
guard let string = container.attributedText?.string as NSString? else { return nil }
let value = string.substring(with: range)
return LinkAccessibilityElement(
accessibilityContainer: container,
range: range,
value: value,
identfier: accessibilityIdentifier
)
}

private func makeContainerAccessibilityElement() -> UIAccessibilityElement? {
Expand Down
6 changes: 3 additions & 3 deletions HyperLabel/HyperLabelProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ import Foundation
public protocol HyperLabelProtocol: AnyObject {
var extendsLinkTouchArea: Bool { get set }
var additionalLinkAttributes: [NSAttributedString.Key: Any] { get set }
func addLink(withRange range: Range<String.Index>,
func addLink(withRange range: NSRange,
accessibilityIdentifier: String?,
handler: @escaping () -> Void)
}

extension HyperLabelProtocol {
public func addLink(withRange range: Range<String.Index>, handler: @escaping () -> Void) {
public func addLink(withRange range: NSRange, handler: @escaping () -> Void) {
self.addLink(withRange: range, accessibilityIdentifier: nil, handler: handler)
}
}
Expand Down Expand Up @@ -82,7 +82,7 @@ extension HyperLabelProtocol where Self: UILabel {
}
}

public func addLink(withRange range: Range<String.Index>,
public func addLink(withRange range: NSRange,
accessibilityIdentifier: String?,
handler: @escaping () -> Void) {
guard let presenter = self.presenter else {
Expand Down
7 changes: 1 addition & 6 deletions HyperLabel/HyperLabelTextStyler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,9 @@ public struct HyperLabelTextStyler {
public var linkAttributes: [NSAttributedString.Key: Any] = [:]

public func applyLinkAttributes(for attributedString: NSAttributedString,
at range: Range<String.Index>) -> NSAttributedString {
at range: NSRange) -> NSAttributedString {
guard !self.linkAttributes.isEmpty else { return attributedString }
let mutable = attributedString.mutableCopy() as! NSMutableAttributedString
// https://bugs.swift.org/browse/SR-11330
guard let data = mutable.string.data(using: .utf16) else { return attributedString }
guard let reconstructed = String(bytes: data, encoding: .utf16) else { return attributedString }
let original = reconstructed + ""
let range = NSRange(range, in: original)
mutable.addAttributes(self.linkAttributes, range: range)
return mutable.copy() as! NSAttributedString
}
Expand Down
4 changes: 2 additions & 2 deletions HyperLabel/LinkAccessibilityElement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import UIKit

final class LinkAccessibilityElement: UIAccessibilityElement {
init(accessibilityContainer container: Any,
range: Range<String.Index>,
range: NSRange,
value: String,
identfier: String) {
self.range = range
Expand All @@ -35,5 +35,5 @@ final class LinkAccessibilityElement: UIAccessibilityElement {
self.accessibilityValue = value
}

let range: Range<String.Index>
let range: NSRange
}
8 changes: 4 additions & 4 deletions HyperLabel/RangeMap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

struct RangeMap<Index: Comparable, Value> {
struct RangeMap<Value> {

private typealias Entry = (range: Range<Index>, value: Value)
private typealias Entry = (range: NSRange, value: Value)
private var storage: [Entry] = []

init() {}

mutating func setValue(value: Value, forRange range: Range<Index>) {
mutating func setValue(value: Value, forRange range: NSRange) {
let entry = (range, value)
self.storage.append(entry)
}

func value(at index: Index) -> Value? {
func value(at index: Int) -> Value? {
for (range, value) in self.storage where range.contains(index) {
return value
}
Expand Down
21 changes: 4 additions & 17 deletions HyperLabel/TextLayoutInfoProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,30 +53,17 @@ final class TextLayoutInfoProvider {
self.textContainer.size = data.size
}

func indexOfCharacter(atPoint point: CGPoint) -> String.Index? {
func indexOfCharacter(atPoint point: CGPoint) -> Int? {
guard self.textStorage.length > 0 else { return nil }
let usedRect = self.layoutManager.usedRect(for: self.textContainer)
guard usedRect.contains(point) else { return nil }
let index = self.layoutManager.glyphIndex(for: point, in: self.textContainer)
#if compiler(>=5)
guard let data = self.textStorage.string.data(using: .utf16) else { return nil }
guard let reconstructed = String(bytes: data, encoding: .utf16) else { return nil }
let original = reconstructed + ""
return String.Index(utf16Offset: index,
in: original)
#else
return String.Index(encodedOffset: index)
#endif
return self.layoutManager.glyphIndex(for: point, in: self.textContainer)
}

func rect(forRange range: Range<String.Index>) -> CGRect {
func rect(forRange range: NSRange) -> CGRect {
var result: CGRect?
guard let data = self.textStorage.string.data(using: .utf16) else { return .zero }
guard let reconstructed = String(bytes: data, encoding: .utf16) else { return .zero }
let original = reconstructed + ""
let nsRange = NSRange(range, in: original)
self.layoutManager.enumerateEnclosingRects(
forGlyphRange: nsRange,
forGlyphRange: range,
withinSelectedGlyphRange: .empty,
in: self.textContainer,
using: { rect, stop in
Expand Down
4 changes: 2 additions & 2 deletions HyperLabelTests/HyperLabelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class HyperLabelTests: XCTestCase {
}()

// When
let range = exampleText.range(of: "day")!
let range = (exampleText as NSString).range(of: "day")

// Then
sut.addLink(withRange: range) {}
Expand All @@ -61,7 +61,7 @@ class HyperLabelTests: XCTestCase {
}()

// When
let range = exampleText.range(of: "characters")!
let range = (exampleText as NSString).range(of: "characters")

// Then
sut.addLink(withRange: range) {}
Expand Down

0 comments on commit 20c3357

Please sign in to comment.