UITextView disabling text selection

2020-02-02 08:04发布

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 fired either)

What am I missing?

11条回答
爷、活的狠高调
2楼-- · 2020-02-02 08:24

You can disable text selection by subclassing UITextView.

The below solution is:

/// 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 {}
    }
}
查看更多
爷的心禁止访问
3楼-- · 2020-02-02 08:25

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

查看更多
▲ chillily
4楼-- · 2020-02-02 08:25

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
查看更多
可以哭但决不认输i
5楼-- · 2020-02-02 08:28

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.

查看更多
闹够了就滚
6楼-- · 2020-02-02 08:30

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.

查看更多
女痞
7楼-- · 2020-02-02 08:43

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.

查看更多
登录 后发表回答