如何以编程方式从UITextField禁用复制粘贴选项

问题描述 投票:40回答:15

我正在制作一个注册警报视图,其中有一个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];

}
ios iphone uitextfield uialertview copy-paste
15个回答
46
投票

这篇文章有很多很好的解决方案:How disable Copy, Cut, Select, Select All in UITextView

我最喜欢的是覆盖canPerformAction:withSender:

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

1
投票

在viewController中尝试这个

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

0
投票

你可以在swift中扩展textview或textfield,如下所示:

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

-1
投票

覆盖targetForAction:withSender是最好的恕我直言:

- (id)targetForAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(paste:)) {
        return nil;
    }
    return [super targetForAction:action withSender:sender];
}

-1
投票

Swift 3.0版

class NoMenuTextField: UITextField {
    override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
        if (action == #selector(NSObject.paste(_:))) {
            return false
        }
        return super.canPerformAction(action, withSender: sender)
    }
}

-3
投票

用于iOS 7或更高版本

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

}


-36
投票

只需设置userInteractionEnabled = NO;


22
投票

对于iOS8.0 +,Xcode 6.0.1,启用了ARC

希望像我一样拯救一个初学者,一段时间实现这个......

实现禁用复制/粘贴/剪切/等。你必须继承UITextField并覆盖...

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

去做这个...

创建一个新类,它是UITextField的子类(即要包含在app文件夹中的新.h和.m文件)。所以File-> New - >“Cocoa Touch Class” - > Next - >“PasteOnlyUITextField”(例如),“UITextField” - > Next-> Create的子类。

一旦为我们新的UITextField子类创建了.h和.m文件,名为“PasteOnlyUITextField”......

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"

现在,您必须以progromically方式或使用身份检查器来使用子类

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

要么...

选择UITextField并转到身份检查器,选择其类。

您可以根据需要更改与菜单选项关联的逻​​辑...

希望这可以帮助!感谢所有原始贡献者。


22
投票

我找到了一种方法,使用swift使用扩展和关联对象而不进行子类化。我使用readonly属性来禁用粘贴/剪切,但可以调整此示例。

Swift 3自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)
    }

}

19
投票

故事板用户可能希望查看此解决方案,只要您可以使用子类化。

我认为通过扩展或协议实现这一目标并不容易。

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

Gist link


12
投票

在ViewController.m中实现此方法此方法将帮助您禁用UITextField上的选项。

它包括您的Corresponding UITextField上的paste,select,selectAll和copy选项。

这个方法在UITextField的情况下非常有用,当你想把它用于密码或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];
}

8
投票

在iOS 9中,我们可以从键盘隐藏复制粘贴栏

-(void) customMethod{

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

}

2
投票

适用于iOS 10及更早版本(Swift 3)的this answer的小更新:

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
投票

注意:在Swift中,如果您希望文本字段禁用所有UIResponderStandardEditActions(剪切,复制,粘贴,查找,共享,选择),请使用UITextFieldDelegate

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

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

1
投票

如果禁用的文本选择适合您,请尝试此操作。

class NoMoreSelectionTextField: UITextField {

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

    override var selectedTextRange: UITextRange? {
        get { return nil }
        set { return }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.