Actually fix link interaction

This commit is contained in:
Shadowfacts 2020-01-18 19:32:39 -05:00
parent 38085eee37
commit 11f9642cba
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
1 changed files with 24 additions and 18 deletions

View File

@ -32,6 +32,10 @@ class ContentTextView: LinkTextView {
textContainerInset = .zero textContainerInset = .zero
textContainer.lineFragmentPadding = 0 textContainer.lineFragmentPadding = 0
// the text view's builtin link interaction code is tied to isSelectable, so we need to use our own tap recognizer
let recognizer = UITapGestureRecognizer(target: self, action: #selector(textTapped(_:)))
addGestureRecognizer(recognizer)
} }
// MARK: - Emojis // MARK: - Emojis
@ -187,6 +191,15 @@ class ContentTextView: LinkTextView {
} }
} }
// only handles link taps via the gesture recognizer which is used when selection is disabled
@objc func textTapped(_ recognizer: UITapGestureRecognizer) {
let location = recognizer.location(in: self)
if let (link, range) = getLinkAtPoint(location) {
let text = (self.text as NSString).substring(with: range)
handleLinkTapped(url: link, text: text)
}
}
func getLinkAtPoint(_ point: CGPoint) -> (URL, NSRange)? { func getLinkAtPoint(_ point: CGPoint) -> (URL, NSRange)? {
let locationInTextContainer = CGPoint(x: point.x - textContainerInset.left, y: point.y - textContainerInset.top) let locationInTextContainer = CGPoint(x: point.x - textContainerInset.left, y: point.y - textContainerInset.top)
var partialFraction: CGFloat = 0 var partialFraction: CGFloat = 0
@ -200,6 +213,16 @@ class ContentTextView: LinkTextView {
return nil return nil
} }
func handleLinkTapped(url: URL, text: String) {
if let mention = getMention(for: url, text: text) {
navigationDelegate?.selected(mention: mention)
} else if let tag = getHashtag(for: url, text: text) {
navigationDelegate?.selected(tag: tag)
} else {
navigationDelegate?.selected(url: url)
}
}
// MARK: - Navigation // MARK: - Navigation
func getViewController(forLink url: URL, inRange range: NSRange) -> UIViewController { func getViewController(forLink url: URL, inRange range: NSRange) -> UIViewController {
@ -231,24 +254,7 @@ class ContentTextView: LinkTextView {
extension ContentTextView: UITextViewDelegate { extension ContentTextView: UITextViewDelegate {
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
let text = (self.text as NSString).substring(with: characterRange) // disable the text view's link interactions, we handle tapping links ourself with a gesture recognizer
switch interaction {
case .invokeDefaultAction:
if let mention = getMention(for: URL, text: text) {
navigationDelegate?.selected(mention: mention)
} else if let tag = getHashtag(for: URL, text: text) {
navigationDelegate?.selected(tag: tag)
} else {
navigationDelegate?.selected(url: URL)
}
case .presentActions:
print("present actions")
case .preview:
print("preview")
@unknown default:
break
}
return false return false
} }
} }