UITextView disabling text selection
Issue How disable Copy, Cut, Select, Select All in UITextView has a workable solution to this that I've just implemented and verified:
Subclass UITextView
and overwrite canBecomeFirstResponder:
- (BOOL)canBecomeFirstResponder {
return NO;
}
Note that this disables links and other tappable text content.
UITextView: Disable selection, allow links
I find the concept of fiddling with the internal gesture recognizers a little scary, so tried to find another solution.
I've discovered that we can override point(inside:with:)
to effectively allow a "tap-through" when the user isn't touching down on text with a link inside it:
// Inside a UITextView subclass:
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
guard let pos = closestPosition(to: point) else { return false }
guard let range = tokenizer.rangeEnclosingPosition(pos, with: .character, inDirection: .layout(.left)) else { return false }
let startIndex = offset(from: beginningOfDocument, to: range.start)
return attributedText.attribute(.link, at: startIndex, effectiveRange: nil) != nil
}
This also means that if you have a UITextView
with a link inside a UITableViewCell
, tableView(didSelectRowAt:)
still gets called when tapping the non-linked portion of the text :)
How to disable a user's ability to select text in a UITextField or UITextView?
The quickest way is to set .isUserInteractionEnabled
to false
on your UITextView
or UITextField
Disable text selection in UITextView
Here comes Swift working example
class TextView: UITextView {
override func canPerformAction(action: Selector, withSender sender: AnyObject!) -> Bool {
return false
}
override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer!) -> Bool {
if gestureRecognizer.isKindOfClass(UITapGestureRecognizer) && ((gestureRecognizer as UITapGestureRecognizer).numberOfTapsRequired == 1) {
let touchPoint = gestureRecognizer.locationOfTouch(0, inView: self)
let cursorPosition = closestPositionToPoint(touchPoint)
selectedTextRange = textRangeFromPosition(cursorPosition, toPosition: cursorPosition)
return true
}
else {
return false
}
}
}
UITextView avoid text selection, but keep tappable links
Add this UITextViewDelegate
textViewDidChangeSelection
and comment out isEditable
and isSelectable
:
func textViewDidChangeSelection(_ textView: UITextView) {
if textView.selectedTextRange != nil {
textView.delegate = nil
textView.selectedTextRange = nil
textView.delegate = self
}
}
Related Topics
Swift - Segmented Control - Switch Multiple Views
Popping and Pushing View Controllers in Same Action
Wait for Async Task to Finish Completion Block Before Returning in App Delegate
Afnetworking 2.0 Track File Upload Progress
Where Are iOS Simulator Screenshots Stored
iOS App Crashing Every Other Launch, Can't Find Error
How to Change Navigation Bar Color in iOS 7 or 6
Invalid Update: Invalid Number of Items on Uicollectionview
How to Use Cocoapods with Playground
How to Add Live Camera Preview to Uiview
Uisearchdisplaycontroller's Searchresultstableview's Contentsize Is Incorrect. Bug in iOS 7
What Happens with Constraints When a View Is Removed
How to Upload Audio with Alamofire Multipart Upload
How to Delete Object from Core Data in Swift 3
Xcode: "Scene Is Unreachable Due to Lack of Entry Points" But Can't Find It