From feba217283209df06ebe94e4057f370b7d6981a3 Mon Sep 17 00:00:00 2001 From: Oliver Clark Rickard Date: Wed, 6 Jun 2018 19:24:43 -0700 Subject: [PATCH] Implement the three-rect selection algorithm --- Source/StyledTextView.swift | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Source/StyledTextView.swift b/Source/StyledTextView.swift index e89437a..5512019 100644 --- a/Source/StyledTextView.swift +++ b/Source/StyledTextView.swift @@ -144,13 +144,37 @@ open class StyledTextView: UIView { let range = NSRange(location: min, length: max - min) + var firstRect: CGRect = CGRect.null + var bodyRect: CGRect = CGRect.null + var lastRect: CGRect = CGRect.null + let path = UIBezierPath() + renderer.layoutManager.enumerateEnclosingRects( forGlyphRange: range, withinSelectedGlyphRange: NSRange(location: NSNotFound, length: 0), in: renderer.textContainer ) { (rect, stop) in - path.append(UIBezierPath(roundedRect: rect.insetBy(dx: -2, dy: -2), cornerRadius: 3)) + if firstRect.isNull { + firstRect = rect + } else if lastRect.isNull { + lastRect = rect + } else { + // We have a lastRect that was previously filled, now it needs to be dumped into the body + bodyRect = lastRect.intersection(bodyRect) + // and save the current rect as the new "lastRect" + lastRect = rect + } + } + + if !firstRect.isNull { + path.append(UIBezierPath(roundedRect: firstRect.insetBy(dx: -2, dy: -2), cornerRadius: 3)) + } + if !bodyRect.isNull { + path.append(UIBezierPath(roundedRect: bodyRect.insetBy(dx: -2, dy: -2), cornerRadius: 3)) + } + if !lastRect.isNull { + path.append(UIBezierPath(roundedRect: lastRect.insetBy(dx: -2, dy: -2), cornerRadius: 3)) } highlightLayer.frame = bounds