Answers:
禁用粘贴板操作的最简单方法是创建一个子类,UITextView
该子类重写该canPerformAction:withSender:
方法以返回NO
您不想执行的操作:
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(paste:))
return NO;
return [super canPerformAction:action withSender:sender];
}
另请参见UIResponder
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { return NO; }
-封锁所有选项
子类UITextView并覆盖canBecomeFirstResponder:
- (BOOL)canBecomeFirstResponder {
return NO;
}
注意,这仅适用于不可编辑的UITextViews!尚未在可编辑的文件上对其进行测试...
return NO;
在- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
方法是一个更好的选择。
如果要在所有 UITextView
应用程序上禁用剪切/复制/粘贴功能,则可以使用带有以下类别的类别:
@implementation UITextView (DisableCopyPaste)
- (BOOL)canBecomeFirstResponder
{
return NO;
}
@end
它保存一个子类... :-)
UITextView
,例如在可编辑和可触摸的情况下,无法按预期表现。要压倒太多canPerformAction:withSender:
; 这就是协议的目的。
这是最适合我的解决方案:
UIView *overlay = [[UIView alloc] init];
[overlay setFrame:CGRectMake(0, 0, myTextView.contentSize.width, myTextView.contentSize.height)];
[myTextView addSubview:overlay];
[overlay release];
@rpetrich的答案对我有用。我正在发布扩展代码,以防它节省一些时间。
就我而言,我不希望弹出窗口,但我确实希望UITextField能够成为第一响应者。
不幸的是,当您按住文本框时,仍然会弹出放大镜。
@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
斯威夫特4
class NoSelectTextField: UITextField {
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
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 false
}
return super.canPerformAction(action, withSender: sender)
}
}
最简单的方法是创建覆盖canPerformAction:withSender的UITextView的子类:
- (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.
我的解决方案如下:
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO];
}];
return [super canPerformAction:action withSender:sender];
}
诀窍是在主队列的下一个循环中隐藏菜单控制器(显示之后)。
这是禁用UITextView中的整个“选择/复制/粘贴”菜单的最简单方法
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
[UIMenuController sharedMenuController].menuVisible = NO;
return NO;
}
如果您希望将键盘替换UIPicker
为,inputView
(当然也将工具栏作为inputAccesotyView
),那么此解决方法可能会有所帮助...
textFieldShouldBeginEditing:
textField.userInteractionEnabled = NO;
UIPickerView
,将其设置为YES。这样,您就可以点击UITextField
并显示从中进行选择的选项UIPickerView
,这时您UITextField
实际上不会对任何触摸事件做出反应(这包括触摸并按住以进行剪切,复制和粘贴)。但是,您必须记住在关闭您的设备时将其设置回YES,UIPickerView
但是您将无法UIPickerView
再次访问它。
失败的唯一时刻是用户通过点击并按住来开始UITextView
,然后您将看到剪切的副本并再次粘贴。这就是为什么您应该始终验证输入的原因。这是我最容易想到的。另一个选择是使用UILabel
只读文本,但是您会错过的许多强大功能UITextView
。
如果要禁用弹出窗口,请UITextField
尝试使用此UITextFieldDelegate
方法进行切换isUserInteractionEnabled
。
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
textField.isUserInteractionEnabled = false
return true
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
textField.isUserInteractionEnabled = true
return true
}
我在这里提供了一个有效的答案,以禁用文本选择+放大镜,并保持启用的可点击链接,希望对您有所帮助:
经过相当长时间的尝试,我通过重写UITextView子类上的addGestureRecognizer来停止文本选择,放大并保持数据检测(链接可单击等),仅允许UILongPressGestureRecognizer延迟触摸结束:
UIUnselectableTextView.m
-(void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
if([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] && gestureRecognizer.delaysTouchesEnded)
{
[super addGestureRecognizer:gestureRecognizer];
}
}
对于Swift 3,它已更改为:
override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return false
}
我已经做了。在我上,UITextView
我非常容易禁用剪切,复制,选择等选项。
我将放在放置了UIView
的同一位置UITextView
,但是在上self.view
添加了以下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.
如果要向UITextView添加自定义选项但禁用现有功能,这是在Swift 3上执行的操作:
要禁用复制,粘贴,剪切功能,请创建一个子类并覆盖以下内容:
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)")
}
此方法将完全禁用“选择”,“全选”,“粘贴”菜单。如果仍然采取其他措施,只需将其添加到if条件,如下所示。
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender // This is to disable select / copy / select all / paste menu
{
if (action == @selector(copy:) || action == @selector(selectAll:) || action == @selector(select:) || action == @selector(paste:))
return NO;
return [super canPerformAction:action withSender:sender];
}
您可以像这样创建类别:
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
(SWIFT)如果只需要一个基本的文本字段,而没有菜单选项或放大镜,则创建一个UITextField的子类,将false返回给gestureRecognizerShouldBegin:
class TextFieldBasic: UITextField {
override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}
}
这将绕过文本字段上的所有触摸功能,但仍允许您使用弹出键盘添加/删除字符。
如果使用情节提要,只需将新创建的类分配给文本字段,或者以编程方式创建文本字段:
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)}
迅捷3
为此,您需要将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)
}
请找到示例代码以供参考:
override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(copy(_:)) || action == #selector(paste(_:)) || action == #selector(UIResponderStandardEditActions.paste(_:)) ||
action == #selector(replace(_:withText:)) ||
action == #selector(UIResponderStandardEditActions.cut(_:)) ||
action == #selector(UIResponderStandardEditActions.select(_:)) ||
action == #selector(UIResponderStandardEditActions.selectAll(_:)) ||
action == #selector(UIResponderStandardEditActions.delete(_:)) ||
action == #selector(UIResponderStandardEditActions.makeTextWritingDirectionLeftToRight(_:)) ||
action == #selector(UIResponderStandardEditActions.makeTextWritingDirectionRightToLeft(_:)) ||
action == #selector(UIResponderStandardEditActions.toggleBoldface(_:)) ||
action == #selector(UIResponderStandardEditActions.toggleItalics(_:)) ||
action == #selector(UIResponderStandardEditActions.toggleUnderline(_:)) ||
action == #selector(UIResponderStandardEditActions.increaseSize(_:)) ||
action == #selector(UIResponderStandardEditActions.decreaseSize(_:))
{
return false
}
return true
}
用于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
}
}
创建一个名为StopPasteAction.swift的新类
import UIKit
class StopPasteAction: UITextField {
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return false
}
}
使用当前的TextField将类添加为新类