web-dev-qa-db-fra.com

UITextView désactivant la sélection de texte

J'ai du mal à obtenir la UITextView pour désactiver la sélection du texte.

J'ai essayé:

canCancelContentTouches = YES;

J'ai essayé de sous-classer et d'écraser:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender   

(Mais cela n'est appelé qu'après la sélection)

- (BOOL)touchesShouldCancelInContentView:(UIView *)view;  

(Je ne vois pas que se faire virer du tout)

- (BOOL)touchesShouldBegin:(NSSet *)touches
                 withEvent:(UIEvent *)event
             inContentView:(UIView *)view; 

(Je ne vois pas que se faire virer non plus)

Qu'est-ce que je rate?

38
dizy

Problème Comment désactiver les fonctions Copier, Couper, Sélectionner, Tout sélectionner dans UITextView propose une solution pratique que je viens d’implémenter et de vérifier:

Sous-classe UITextView et écraser canBecomeFirstResponder:

- (BOOL)canBecomeFirstResponder {
    return NO;
}

Notez que cela désactive les liens et tout autre contenu textuel pouvant être mappé.

76
Dafydd Williams

J'ai trouvé cet appel

[textView setUserInteractionEnabled:NO];

fonctionne assez bien.

46
James M

UITextView 's selectable property:

Cette propriété contrôle la capacité de l'utilisateur à sélectionner du contenu et interagir avec les URL et les pièces jointes. La valeur par défaut est OUI.

13
Heath Borders

Cela ressemble à ce que vous voulez réellement, c'est un UILabel géant à l'intérieur d'un UIScrollView et non un UITextView.

update: si vous utilisez des versions plus récentes d'iOS, UILabel a maintenant une propriété lines:

Plusieurs lignes de texte dans UILabel

9
slf

Si vous souhaitez simplement empêcher sa modification, définissez la propriété "editable" de UITextView sur NO/False.

Si vous essayez de le laisser éditable mais non sélectionnable, cela va être délicat. Vous devrez peut-être créer une vue de texte masquée dans laquelle l'utilisateur peut taper, puis laisser UITextView l'observer et la renseigner lui-même avec le texte de la vue 

5
TechZen

Pour ce faire, commencez par classer UITextView 

et dans la mise en œuvre faire ce qui suit 

- (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;
 }

cela devrait bien fonctionner, 

2
Sajad Goudarzi

Vous pouvez désactiver la sélection de texte en sous-classant UITextView.

La solution ci-dessous est:

/// 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 {}
    }
}
1
Cœur

Avez-vous essayé de définir userInteractionEnabled sur NO pour votre UITextView? Mais vous perdriez aussi le défilement.

Si vous avez besoin de défilement, c'est probablement pour cette raison que vous avez utilisé UITextView et non pas UILabel, vous devez alors effectuer davantage de travail. Vous devrez probablement remplacer canPerformAction:withSender: pour renvoyer NO pour les actions que vous ne souhaitez pas autoriser:

- (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];
}

Pour plus, UIResponderStandardEditActions .

1
mahboudz

Swift 4 , Xcode 10

Cette solution va 

  • désactiver la surbrillance
  • activer les liens de taraudage
  • permettre le défilement

Assurez-vous de définir le délégué sur YourViewController

yourTextView.delegate = yourViewControllerInstance

Ensuite

extension YourViewController: UITextViewDelegate {

    func textViewDidChangeSelection(_ textView: UITextView) {
        view.endEditing(true)
    }

}
1
Ted

Pour Swift, il existe une propriété appelée "isSelectable" et sa valeur par défaut est true 

vous pouvez l'utiliser comme suit:

textView.isSelectable = false
0

Swift 4, Xcode 10:

Si vous souhaitez que l'utilisateur ne puisse ni sélectionner ni modifier le texte.

Cela fait en sorte qu'il ne peut pas être édité:

textView.isEditable = false

Ceci désactive toute interaction utilisateur:

textView.isUserInteractionEnabled = false

Cela fait en sorte que vous ne pouvez pas le sélectionner. Cela signifie que les options d'édition et de collage ne seront pas affichées. Je pense que c'est ce que vous recherchez.

textView.isSelectable = false
0
aaronmbmorse