Last active
June 4, 2018 18:40
-
-
Save yesleon/ad74f31b9ee86012fce8d476db1d949a to your computer and use it in GitHub Desktop.
This enables UITextView to be editable when being data detectable. Just set isEditableWhenBeingDataDetectable to true.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UITextView+isEditableWhenBeingDataDetectable.swift | |
// | |
// Created by Li-Heng Hsu on 15/05/2018. | |
// Copyright © 2018 narrativesaw. All rights reserved. | |
// | |
import UIKit | |
extension UITextView { | |
@objc private func didReceiveTap(_ sender: UITapGestureRecognizer) { | |
guard sender.view === self else { return } | |
let location = sender.location(in: self) | |
guard let position = closestPosition(to: location) else { return } | |
let styleDictionary = textStyling(at: position, in: .forward) ?? [:] | |
openURL: if let url = styleDictionary[NSAttributedStringKey.link.rawValue] as? URL { | |
let location = offset(from: beginningOfDocument, to: position) | |
if delegate?.textView?(self, shouldInteractWith: url, in: NSRange(location: location, length: 0), interaction: .invokeDefaultAction) == false { | |
break openURL | |
} | |
UIApplication.shared.open(url) | |
} else if let range = textRange(from: position, to: position) { | |
isEditable = true | |
becomeFirstResponder() | |
selectedTextRange = range | |
} | |
} | |
@IBInspectable | |
var isEditableWhenBeingDataDetectable: Bool { | |
get { | |
return gestureRecognizers?.contains { $0 is LHTextViewEditableWhenBeingDataDetactableEnabler } == true | |
} | |
set { | |
if newValue { | |
if !isEditableWhenBeingDataDetectable { | |
let enabler = LHTextViewEditableWhenBeingDataDetactableEnabler(target: self, action: #selector(didReceiveTap)) | |
addGestureRecognizer(enabler) | |
} | |
} else { | |
if let enabler = gestureRecognizers?.first(where: { $0 is LHTextViewEditableWhenBeingDataDetactableEnabler }) { | |
removeGestureRecognizer(enabler) | |
} | |
} | |
} | |
} | |
} | |
private class LHTextViewEditableWhenBeingDataDetactableEnabler: UITapGestureRecognizer { | |
override init(target: Any?, action: Selector?) { | |
super.init(target: target, action: action) | |
delegate = self | |
NotificationCenter.default.addObserver(self, selector: #selector(didEndEditing), name: .UITextViewTextDidEndEditing, object: nil) | |
} | |
deinit { | |
NotificationCenter.default.removeObserver(self) | |
} | |
@objc private func didEndEditing(notification: Notification) { | |
guard (notification.object as AnyObject) === view else { return } | |
(view as? UITextView)?.isEditable = false | |
} | |
} | |
extension LHTextViewEditableWhenBeingDataDetactableEnabler: UIGestureRecognizerDelegate { | |
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { | |
guard let textView = gestureRecognizer.view as? UITextView else { return false } | |
return !textView.isEditable | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment