如何禁用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;
- 然后,当您即将closures
UIPickerView
,将其设置为YES。
通过这样做,您可以点击UITextField
并显示从UIPickerView
select的选项,此时,您的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)") }