如何禁用UITextView中的复制,剪切,select,全选

当我按下屏幕时, UITextView的复制,剪切,select,全选function默认显示。 但是,在我的项目中, UITextField只能读取。 我不需要这个function。 请告诉我如何禁用此function。

禁用粘贴板操作的最简单方法是创build一个覆盖canPerformAction:withSender:UITextView的子类canPerformAction:withSender:方法返回NO用于不允许的操作:

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

另请参阅UIResponder

子类UITextView并覆盖canBecomeFirstResponder:

 - (BOOL)canBecomeFirstResponder { return NO; } 

请注意,这只适用于不可编辑的UITextView! 没有在可编辑的testing中…

如果你想在你的应用程序的所有 UITextView上禁用剪切/复制/粘贴,你可以使用一个类别

 @implementation UITextView (DisableCopyPaste) - (BOOL)canBecomeFirstResponder { return NO; } @end 

它保存了一个子类… 🙂

这对我来说是最好的工作解决scheme:

 UIView *overlay = [[UIView alloc] init]; [overlay setFrame:CGRectMake(0, 0, myTextView.contentSize.width, myTextView.contentSize.height)]; [myTextView addSubview:overlay]; [overlay release]; 

从: https : //stackoverflow.com/a/5704584/1293949

如果你不需要UITextView来滚动,那么不涉及子类的最简单的解决scheme是简单地禁用文本视图的用户交互:

 textField.userInteractionEnabled = NO; 

最简单的方法是创build一个覆盖canPerformAction的UITextView的子类:withSender:

 - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { [UIMenuController sharedMenuController].menuVisible = NO; //do not display the menu [self resignFirstResponder]; //do not allow the user to selected anything return NO; } 

当我在iOS 7的canPerformAction中返回NO时,会出现很多这样的错误:

<Error>: CGContextSetFillColorWithColor: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

我的解决scheme如下:

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

诀窍是在主队列的下一个循环中隐藏菜单控制器(刚刚显示之后)。

这是禁用UITextView中的整个select/复制/粘贴菜单的最简单的方法

 -(BOOL)canPerformAction:(SEL)action withSender:(id)sender { [UIMenuController sharedMenuController].menuVisible = NO; return NO; } 

@ rpetrich答案为我工作。 我张贴扩展的代码,以防止一些人保存一些时间。

在我的情况下,我不想popup任何东西,但我希望UITextField能够成为第一响应者。

不幸的是,当你点击并按住文本框时,仍然会popup放大镜。

 @interface NoSelectTextField : UITextField @end @implementation NoSelectTextField - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { if (action == @selector(paste:) || action == @selector(cut:) || action == @selector(copy:) || action == @selector(select:) || action == @selector(selectAll:) || action == @selector(delete:) || action == @selector(makeTextWritingDirectionLeftToRight:) || action == @selector(makeTextWritingDirectionRightToLeft:) || action == @selector(toggleBoldface:) || action == @selector(toggleItalics:) || action == @selector(toggleUnderline:) ) { return NO; } return [super canPerformAction:action withSender:sender]; } @end 

如果你正在寻找replace键盘,让我们说, UIPicker作为inputView (当然一个工具栏作为inputAccesotyView ),那么这种解决方法可能会帮助…

  • 实现textFieldShouldBeginEditing:
  • 里面放了textField.userInteractionEnabled = NO;
  • 然后,当您即将closuresUIPickerView ,将其设置为YES。

通过这样做,您可以点击UITextField并显示从UIPickerViewselect的选项,此时,您的UITextField确实不会对任何触摸事件作出反应(这包括触摸并保持剪切,复制糊)。 但是,当你closures你的UIPickerView时,你必须记得把它设置回YES,但是你将不能再次访问你的UIPickerView

唯一一个失败的时刻是当用户点击并按住UITextView ,你会看到第一次剪切复制和粘贴。 这就是为什么你总是应该validation你的input。 这是我能想到的最简单的方法。 另一个select是使用UILabel作为只读文本,但是却错过了UITextView的很多function。

由于iOS 7在UITextView上有一个属性:

  @property(nonatomic,getter=isSelectable) BOOL selectable; 

这保持了允许文本select的视图。 对我很好。

这对我有效。 确保你在textView上调用了resignFirstRresponder

 -(BOOL)canPerformAction:(SEL)action withSender:(id)sender { [self.textView resignFirstResponder]; return NO; } 

我在这里提供了一个工作的答案来禁用文本select+放大镜,保持启用可克联的链接希望帮助:

经过相当长的时间的努力,我设法停止文本select,放大,并保持数据检测(链接点击等),通过覆盖的UITextView子类addGestureRecognizer只允许UILongPressGestureRecognizer延迟触摸结束:

UIUnselectableTextView.m

 -(void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer { if([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] && gestureRecognizer.delaysTouchesEnded) { [super addGestureRecognizer:gestureRecognizer]; } } 

这可以在故事板(Xcode 6)中轻松完成。 只需在“属性”检查器中取消选中“可编辑”和“可选”即可。 您仍然可以滚动文本视图。 在这里输入图像描述

对于Swift 3,它被改为:

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

我已经做了。 在我的UITextView我已经禁用剪切,复制,select等选项很容易。

我把UIView放在我放置UITextView ,但在touchDelegate上,并添加了一个touchDelegate方法,如下所示:

 (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *scrollTouch=[touches anyObject]; if(scrollTouch.view.tag==1) { NSLog(@"viewTouched"); if(scrollTouch.tapCount==1) [textView1 becomeFirstResponder]; else if(scrollTouch.tapCount==2) { NSLog(@"double touch"); return; } } } 

它为我工作。 谢谢。

迅速

 textView.selectable = false // disable text selection (and thus copy/paste/etc) 

有关

 textView.editable = false // text cannot be changed but can still be selected and copied textView.userInteractionEnabled = false // disables all interaction, including scrolling, clicking on links, etc. 

您可以通过取消选中以下框来修复故事板中的内容:

在这里输入图像描述

或者你可以像这样编程设置:

 textView.selectable = false textView.editable = false 

你可以像这样创build类别:

的UITextView + Selectable.h

 @interface UITextView (Selectable) @property (nonatomic, assign, getter = isTextSelectable) bool textSelectable; @end 

的UITextView + Selectable.m

 #import "UITextView+Selectable.h" #import <objc/runtime.h> #define TEXT_SELECTABLE_PROPERTY_KEY @"textSelectablePropertyKey" @implementation UITextView (Selectable) @dynamic textSelectable; -(void)setTextSelectable:(bool)textSelectable { objc_setAssociatedObject(self, TEXT_SELECTABLE_PROPERTY_KEY, [NSNumber numberWithBool:textSelectable], OBJC_ASSOCIATION_ASSIGN); } -(bool)isTextSelectable { return [objc_getAssociatedObject(self, TEXT_SELECTABLE_PROPERTY_KEY) boolValue]; } -(bool)canBecomeFirstResponder { return [self isTextSelectable]; } @end 

子类化UITextView并重写- (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer是另一种禁用不需要的操作的可能性。

使用gestureRecognizer的类来决定是否添加动作。

(SWIFT)如果只需要一个没有菜单选项或放大镜的基本文本字段,则创buildUITextField的子类,将false返回给gestureRecognizerShouldBegin:

 class TextFieldBasic: UITextField { override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool { return false } } 

这将绕过文本字段的所有触摸function,但仍然允许您使用popup式键盘添加/删除字符。

如果您正在使用故事板,只需将新创build的类分配给文本字段,或者如果您正在编程创build文本字段:

 var basicTextField = TextFieldBasic() basic = basicTextField(frame: CGRectMake(10, 100, 100,35)) basic.backgroundColor = UIColor.redColor() self.view.addSubview(basic) basic.becomeFirstResponder() 
 override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool { NSOperationQueue .mainQueue().addOperationWithBlock({ () -> Void in [UIMenuController .sharedMenuController() .setMenuVisible(false, animated: true)] }) return super.canPerformAction(action, withSender: sender)} 

Swift 3

为了做到这一点,你需要inheritance你的UITextView并把这个方法。

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

使用func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { retrun bool }代替textFieldShouldBeginEditing

 class ViewController: UIViewController , UITextFieldDelegate { @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() //Show date picker let datePicker = UIDatePicker() datePicker.datePickerMode = UIDatePickerMode.date textField.tag = 1 textField.inputView = datePicker } func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { if textField.tag == 1 { textField.text = "" return false } return true } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField.tag == 1 { textField.text = "" return false } return true } } 

创build一个名为StopPasteAction.swift的新类

 import UIKit class StopPasteAction: UITextField { override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool { return false } } 

添加当前TextField的类新类

在这里输入图像描述

如果你想添加一个自定义选项到你的UITextView,但禁用现有的function,这是你如何做到这一点在Swift 3

要禁用复制,粘贴,剪切funcionality,请创build一个子类并覆盖以下内容:

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

在ViewController上你有你的CustomTextView添加以下内容来添加你的选项:

  let selectText = UIMenuItem(title: "Select", action: #selector(ViewController.selected)) func selected() { if let selectedRange = textView.selectedTextRange, let selectedText = textView.text(in: selectedRange) { } print("User selected text: \(selectedText)") }