UITextView disabling text selection
I'm having a hard time getting the UITextView
to disable the selecting of the text.
I've tried:
canCancelContentTouches = YES;
I've tried subclassing and overwriting:
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
(But that gets called only After the selection)
- (BOOL)touchesShouldCancelInContentView:(UIView *)view;
(I don't see that getting fired at all)
- (BOOL)touchesShouldBegin:(NSSet *)touches
withEvent:(UIEvent *)event
inContentView:(UIView *)view;
(I don't see that getting fir开发者_StackOverflow中文版ed either)
What am I missing?
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.
I've found that calling
[textView setUserInteractionEnabled:NO];
works quite well.
UITextView
's selectable
property:
This property controls the ability of the user to select content and interact with URLs and text attachments. The default value is YES.
Swift 4, Xcode 10
This solution will
- disable highlighting
- enable tapping links
- allow scrolling
Make sure you set the delegate to YourViewController
yourTextView.delegate = yourViewControllerInstance
Then
extension YourViewController: UITextViewDelegate {
func textViewDidChangeSelection(_ textView: UITextView) {
if #available(iOS 13, *) {
textView.selectedTextRange = nil
} else {
view.endEditing(true)
}
}
}
Swift 4, Xcode 10:
If you want to make it so the user isn't able to select or edit the text.
This makes it so it can not be edited:
textView.isEditable = false
This disables all user interaction:
textView.isUserInteractionEnabled = false
This makes it so that you can't select it. Meaning it will not show the edit or paste options. I think this is what you are looking for.
textView.isSelectable = false
It sounds like what you actually want is a giant UILabel inside a UIScrollView, and not a UITextView.
update: if you are on newer versions of iOS UILabel now has a lines property:
Multiple lines of text in UILabel
If you just want to prevent it from being edited, then set the UITextView's "editable" property to NO/False.
If you're trying to leave it editable but not selectable, that's going to be tricky. You might need to create a hidden textview that the user can type into and then have UITextView observe that hidden textview and populate itself with the textview's text.
To do this first subclass the UITextView
and in the implementation do the following
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
self.selectable = NO;
}
- (void)touchesCancelled:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
self.selectable = YES;
}
this should work fine,
Did you try setting userInteractionEnabled to NO for your UITextView? But you'd lose scrolling too.
If you need scrolling, which is probably why you used a UITextView and not a UILabel, then you need to do more work. You'll probably have to override canPerformAction:withSender:
to return NO
for actions that you don't want to allow:
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
switch (action) {
case @selector(paste:):
case @selector(copy:):
case @selector(cut:):
case @selector(cut:):
case @selector(select:):
case @selector(selectAll:):
return NO;
}
return [super canPerformAction:action withSender:sender];
}
For more, UIResponderStandardEditActions .
You can disable text selection by subclassing UITextView
.
The below solution is:
- compatible with isScrollEnabled
- compatible with loupe/magnifier
- but not compatible with links (see here for a solution compatible with links)
/// Class to disallow text selection
/// while keeping support for loupe/magnifier and scrolling
/// https://stackoverflow.com/a/49428248/1033581
class UnselectableTextView: UITextView {
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
// prevents selection from loupe/magnifier (_UITextSelectionForceGesture), multi tap, tap and a half, etc.
// without losing the loupe/magnifier or scrolling
// but we lose taps on links
addSubview(transparentOverlayView)
}
let transparentOverlayView: UIView = {
$0.backgroundColor = .clear
$0.autoresizingMask = [.flexibleHeight, .flexibleWidth]
return $0
}(UIView())
override var contentSize: CGSize {
didSet {
transparentOverlayView.frame = CGRect(origin: .zero, size: contentSize)
}
}
// required to prevent blue background selection from any situation
override var selectedTextRange: UITextRange? {
get { return nil }
set {}
}
}
For swift, there is a property called "isSelectable" and its by default assign to true
you can use it as follow:
textView.isSelectable = false
精彩评论