web-dev-qa-db-fra.com

Comment désactiver l'option copier-coller à partir de UITextField par programme

Je crée une alerte d’enregistrement qui contient un UITextField dans lequel l’utilisateur peut entrer son numéro d’enregistrement. tout est à peu près leur, cependant je voudrais supprimer la fonction copier-coller du champ de texte par programme car il n'y a pas de version InterfaceBuilder du champ de texte je ne sais pas comment faire cela. 

voici mon UIalertview à ce jour ...

- (void)pleaseRegisterDevice {

    UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:@"Please Register Device!" message:@"this gets covered" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    regTextField = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 45.0, 260.0, 25.0)];
    [regTextField setBackgroundColor:[UIColor whiteColor]];
    regTextField.textAlignment = UITextAlignmentCenter;
    [myAlertView addSubview:regTextField];
    [myAlertView show];
    [myAlertView release];

}
38
C.Johns

Cet article a de nombreuses solutions intéressantes: Comment désactiver les fonctions Copier, Couper, Sélectionner, Tout sélectionner dans UITextView

Mon préféré est de remplacer canPerformAction:withSender::

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(paste:))
        return NO;
    return [super canPerformAction:action withSender:sender];
}
46
PengOne

J'ai trouvé un moyen d'utiliser Swift en utilisant l'extension et relatedObject sans sous-classement . J'utilise une propriété en lecture seule pour désactiver le collage/couper, mais cet exemple peut être adapté.

Swift 3 mis à jour le 27/11/2016

var key: Void?

class UITextFieldAdditions: NSObject {
    var readonly: Bool = false
}

extension UITextField {
    var readonly: Bool {
        get {
           return self.getAdditions().readonly
     } set {
        self.getAdditions().readonly = newValue
    }
}

private func getAdditions() -> UITextFieldAdditions {
    var additions = objc_getAssociatedObject(self, &key) as? UITextFieldAdditions
    if additions == nil {
        additions = UITextFieldAdditions()
        objc_setAssociatedObject(self, &key, additions!, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    }
    return additions!
}

open override func target(forAction action: Selector, withSender sender: Any?) -> Any? {
    if ((action == #selector(UIResponderStandardEditActions.paste(_:)) || (action == #selector(UIResponderStandardEditActions.cut(_:)))) && self.readonly) {
        return nil
    }
    return super.target(forAction: action, withSender: sender)
}

}

Autres Swift (2.2)

import UIKit

var key: Void?

class UITextFieldAdditions: NSObject {
    var readonly: Bool = false
}

extension UITextField {
    var readonly: Bool {
        get {
            return self.getAdditions().readonly
        }
        set {
            self.getAdditions().readonly = newValue
        }
    }

    private func getAdditions() -> UITextFieldAdditions {
        var additions = objc_getAssociatedObject(self, &key) as? UITextFieldAdditions
        if additions == nil {
            additions = UITextFieldAdditions()
            objc_setAssociatedObject(self, &key, additions!, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
        }
        return additions!
    }

    public override func targetForAction(action: Selector, withSender sender: AnyObject?) -> AnyObject? {
        if ((action == Selector("paste:") || (action == Selector("cut:"))) && self.readonly) {
            return nil
        }
        return super.targetForAction(action, withSender: sender)
    }

}
23
dtissera

Pour iOS8.0 +, Xcode 6.0.1, ARC activé

En espérant sauver un débutant, comme moi, un peu de temps pour le mettre en oeuvre ...

Pour implémenter la désactivation du copier/coller/couper/etc. vous devez sous-classer UITextField et substituer ...

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

Pour faire ça...  

Créez une nouvelle classe qui est une sous-classe de UITextField (c'est-à-dire de nouveaux fichiers .h et .m à inclure dans votre dossier d'application). Ainsi, Fichier-> Nouveau -> "Cocoa Touch Class" -> Suivant -> "PasteOnlyUITextField" (par exemple), sous-classe de "UITextField" -> Suivant-> Créer.

Une fois les fichiers .h et .m créés pour notre nouvelle sous-classe de UITextField intitulée "PasteOnlyUITextField" ...

PasteOnlyUITextField.h

#import <UIKit/UIKit.h>

@interface PasteOnlyUITextField : UITextField

@end

CollerOnlyUITextField.m

#import "PasteOnlyUITextField.h"

@implementation PasteOnlyUITextField

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(paste:))
    {
        return true;
    }

    return false;
}

@end

Maintenant, assurez-vous d'importer PasteOnlyUITextField.h à l'emplacement où vous allez l'utiliser, par exemple. YourUIViewController.h fichier ...

#import "PasteOnlyUITextField.h"

Vous devez maintenant utiliser la sous-classe, par programme ou avec un inspecteur d'identité

PasteOnlyUITextField *pasteOnlyUITextField = [[PasteOnlyUITextField alloc] init...];

ou...

Sélectionnez UITextField et accédez à l'inspecteur d'identité, sélectionnez sa classe.

identity inspector

Vous pouvez modifier la logique associée aux options de menu comme bon vous semble ...

J'espère que cela t'aides! Merci à tous les contributeurs originaux.

22
serge-k

Les utilisateurs de Storyboard peuvent vouloir examiner cette solution, tant que vous êtes d'accord avec le sous-classement. 

Je ne pense pas qu'il existe un moyen facile d'y parvenir via des extensions ou des protocoles.

Swift 3.1

import UIKit

@IBDesignable
class CustomTextField: UITextField {

    @IBInspectable var isPasteEnabled: Bool = true

    @IBInspectable var isSelectEnabled: Bool = true

    @IBInspectable var isSelectAllEnabled: Bool = true

    @IBInspectable var isCopyEnabled: Bool = true

    @IBInspectable var isCutEnabled: Bool = true

    @IBInspectable var isDeleteEnabled: Bool = true

    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        switch action {
        case #selector(UIResponderStandardEditActions.paste(_:)) where !isPasteEnabled,
             #selector(UIResponderStandardEditActions.select(_:)) where !isSelectEnabled,
             #selector(UIResponderStandardEditActions.selectAll(_:)) where !isSelectAllEnabled,
             #selector(UIResponderStandardEditActions.copy(_:)) where !isCopyEnabled,
             #selector(UIResponderStandardEditActions.cut(_:)) where !isCutEnabled,
             #selector(UIResponderStandardEditActions.delete(_:)) where !isDeleteEnabled:
            return false
        default:
            //return true : this is not correct
            return super.canPerformAction(action, withSender: sender)
        }
    }
}

Lien Gist

14
gujci

Implémentez cette méthode dans ViewController.m Cette méthode vous aidera à désactiver les options sur UITextField

Il comprend les options coller, sélectionner, sélectionner tout et copier de votre UITextField correspondante.

Cette méthode est très utile dans le cas de UITextField lorsque vous voulez utiliser ceci comme mot de passe ou DateOfBirth ou ce que vous voulez. 

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if ((_TextField1 isFirstResponder] || [_TextFied2 isFirstResponder]) {
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO];
        }];
    }
    return [super canPerformAction:action withSender:sender];
}
11
Himani Sharma

Dans iOS 9, nous pouvons masquer la barre de copier-coller du clavier

-(void) customMethod{

   yourTextField.inputAssistantItem.leadingBarButtonGroups = @[];
   yourTextField.inputAssistantItem.trailingBarButtonGroups = @[];

}
8
Himanshu Sraswat

Petite mise à jour de cette réponse pour iOS 10 et versions antérieures (Swift 3):

open override func target(forAction action: Selector, withSender sender: Any?) -> Any? {
    guard isReadonly else {
        return super.target(forAction: action, withSender: sender)
    }

    if #available(iOS 10, *) {
        if action == #selector(UIResponderStandardEditActions.paste(_:)) {
            return nil
        }
    } else {
        if action == #selector(paste(_:)) {
            return nil
        }
    }

    return super.target(forAction: action, withSender: sender)
}
2
Raginmari

Essayez ceci dans votre vueController  

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO];
        }];
        return [super canPerformAction:action withSender:sender];
    }
1
Ali

Remarque: dans Swift, si vous souhaitez que votre champ de texte désactive toutes les UIResponderStandardEditActions (couper, copier, coller, rechercher, partager, sélectionner), utilisez la valeur suivante: UITextFieldDelegate.

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    textField.isUserInteractionEnabled = false
    return true
}

func textFieldDidEndEditing(_ textField: UITextField) {
    textField.isUserInteractionEnabled = true
}
1
mstntsnr

Si la sélection de texte désactivée fonctionne pour vous, essayez ceci.

class NoMoreSelectionTextField: UITextField {

    override func caretRect(for position: UITextPosition) -> CGRect {
        return CGRect.zero
    }

    override var selectedTextRange: UITextRange? {
        get { return nil }
        set { return }
    }
}
1
ukaszm

vous pouvez étendre textview ou textfield dans Swift, comme ceci:

extension UITextView {    
    open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    return false
    }
}
0
nox