web-dev-qa-db-ja.com

UITextFieldからのコピーペーストオプションをプログラムで無効にする方法

ユーザーが登録番号を入力できるUITextFieldを含む登録アラートビューを作成しています。すべてがほとんどですが、テキストフィールドのInterfaceBuilderバージョンではないため、プログラムでテキストフィールドからコピーペースト機能を削除したいと思います。

ここまでが私のUIalertviewです...

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

}
42
C.Johns

この投稿には多くの素敵なソリューションがあります: ITextViewでコピー、切り取り、選択、すべて選択を無効にする方法

私のお気に入りはcanPerformAction:withSender:

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

サブクラス化せずにextensionとrelatedObjectを使用するSwiftを使用する方法を見つけました。プロパティの読み取り専用を使用して貼り付け/切り取りを無効にしますが、このサンプルは適応できます。

Swift 2016年11月27日更新

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)
}

}

その他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)
    }

}
22
dtissera

IOS8.0以降、Xcode 6.0.1、ARC対応

私と同じように、これを実装するのにしばらく時間がかかる...

無効化するコピー/貼り付け/カット/などを実装します。 UITextFieldをサブクラス化し、オーバーライドする必要があります...

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

これを行うには...

UITextFieldのサブクラスである新しいクラスを作成します(アプリフォルダー内に含める新しい.hおよび.mファイル)。したがって、ファイル->新規-> "ココアタッチクラス"->次-> "PasteOnlyUITextField"(たとえば)、 "UITextField"->次->作成のサブクラス。

「PasteOnlyUITextField」というUITextFieldの新しいサブクラスに対して.hおよび.mファイルが作成されると...

PasteOnlyUITextField.h

#import <UIKit/UIKit.h>

@interface PasteOnlyUITextField : UITextField

@end

PasteOnlyUITextField.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

ここで、PasteOnlyUITextField.hを使用する場所にインポートしてください。例:YourUIViewController.hファイル...

#import "PasteOnlyUITextField.h"

ここで、サブクラスを使用する必要があります、プログロマティックまたはIDインスペクターを使用して

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

または...

UITextFieldを選択し、IDインスペクターに移動して、そのクラスを選択します。

identity inspector

必要に応じて、メニューオプションに関連付けられたロジックを変更できます...

お役に立てれば!すべての元の貢献者に感謝します。

22
serge-k

ストーリーボードユーザーは、サブクラス化に問題がない限り、このソリューションを検討することをお勧めします。

拡張機能やプロトコルを介してこれを達成する簡単な方法はないと思います。

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)
        }
    }
}

要旨リンク

21
gujci

ViewController.mでこのメソッドを実装するこのメソッドは、UITextFieldのオプションを無効にするのに役立ちます。

これには、対応するUITextFieldの貼り付け、選択、selectAllおよびコピーオプションが含まれます。

このメソッドは、UITextFieldの場合、またはこれをPasswordまたはDateOfBirthのいずれかにしたい場合に非常に便利です。

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

IOS 9では、キーボードからコピーペーストバーを非表示にできます

-(void) customMethod{

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

}
8

IOS 10以前(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

注:Swiftで、テキストフィールドですべてのUIResponderStandardEditActions(カット、コピー、貼り付け、検索、共有、選択)を無効にするには、UITextFieldDelegateを使用します。

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

func textFieldDidEndEditing(_ textField: UITextField) {
    textField.isUserInteractionEnabled = true
}
2
alitosuner

viewControllerでこれを試してください

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

無効なテキスト選択が機能する場合は、これを試してください。

class NoMoreSelectionTextField: UITextField {

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

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

Swift 5ソリューション:

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    if action == #selector(UIResponderStandardEditActions.copy(_:)) || action == #selector(UIResponderStandardEditActions.paste(_:)) {
        return false
    }

    return true
}
0
Hugo Jordao

次のように、Swiftでtextviewまたはtextfieldを拡張できます。

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