ios 如何在 UITextView 中禁用复制、剪切、选择、全选

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1426731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:23:57  来源:igfitidea点击:

How disable Copy, Cut, Select, Select All in UITextView

iosobjective-cuitextview

提问by Aishwarya

The UITextView's Copy, Cut, Select, Select All functionality is shown by default when I press down on the screen. But, in my project the UITextFieldis only read only. I do not require this functionality. Please tell me how to disable this feature.

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

回答by rpetrich

The easiest way to disable pasteboard operations is to create a subclass of UITextViewthat overrides the canPerformAction:withSender:method to return NOfor actions that you don't want to allow:

禁用粘贴板操作的最简单方法是创建一个子类,UITextView该子类覆盖canPerformAction:withSender:方法以返回NO您不想允许的操作:

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

Also see UIResponder

另见UIResponder

回答by iCoder

Subclass UITextView and overwrite canBecomeFirstResponder:

子类化 UITextView 并覆盖 canBecomeFirstResponder:

- (BOOL)canBecomeFirstResponder {
    return NO;
}

Note, that this only applies for non-editable UITextViews! Haven't tested it on editable ones...

请注意,这仅适用于不可编辑的 UITextViews!还没有在可编辑的上测试过...

回答by Damien Debin

If you want to disable cut/copy/paste on allUITextViewof your application you can use a categorywith :

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

@implementation UITextView (DisableCopyPaste)

- (BOOL)canBecomeFirstResponder
{
    return NO;
}

@end

It saves a subclassing... :-)

它节省了一个子类... :-)

回答by Saraiva Alcides

This was the best working solution for me:

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

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

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

来自:https: //stackoverflow.com/a/5704584/1293949

回答by Luke Redpath

If you don't need UITextView to scroll, then the simplest solution that doesn't involve sub-classing is to simply disable user interaction for the text view:

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

textField.userInteractionEnabled = NO;

回答by pinch

@rpetrich answer worked for me. I'm posting the expanded code in case it saves someone some time.

@rpetrich 的回答对我有用。我正在发布扩展代码,以防它为某人节省一些时间。

In my case I want no popup whatsoever, but I do want the UITextField to be able to become first responder.

在我的情况下,我不想要任何弹出窗口,但我确实希望 UITextField 能够成为第一响应者。

Unfortunately, you still get the magnifier popup when you tap and hold the textfield.

不幸的是,当您点击并按住文本字段时,您仍然会看到放大镜弹出窗口。

@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

Swift 4

斯威夫特 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)
    }

}

回答by haiLong

The easiest way is to create a subclass of UITextView that overrides the canPerformAction:withSender:

最简单的方法是创建一个覆盖 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;
}

回答by Adam Wallner

When I return NO in the canPerformAction on iOS 7 I will get a lot of errors like this:

当我在 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.

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

My solution is the following:

我的解决方案如下:

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

The trick is to hide the menu controller in the next cycle on the main queue (just after it is displayed).

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

回答by GL777

This is the easiest way to disable the entire Select/Copy/Paste Menu in a UITextView

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

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

回答by rn3sto

If you are looking to replace the keyboard with a, let's say, UIPickeras the inputView(with of course a toolbar as an inputAccesotyView), then this workaround might help...

如果您想用 a 替换键盘,比如说,UIPicker作为inputView(当然还有一个工具栏作为inputAccesotyView),那么这个解决方法可能会有所帮助......

  • Implement textFieldShouldBeginEditing:
  • inside put textField.userInteractionEnabled = NO;
  • Then when you are about to close the UIPickerView, set it to YES.
  • 实施 textFieldShouldBeginEditing:
  • 里面放 textField.userInteractionEnabled = NO;
  • 然后,当您要关闭 时UIPickerView,将其设置为 YES。

By doing this, you'd be able to tap on the UITextFieldand show the options to choose from the UIPickerView, at this time your UITextFieldwould, indeed, not react to any touch event (this includes touch and hold for cut, copy and paste). However, you would have to remember to set it back to YES when you are closing your UIPickerViewhowever you won't be able to access your UIPickerViewagain.

通过这样做,您将能够点击UITextField并显示从 中进行选择的选项UIPickerView,此时您UITextField确实不会对任何触摸事件做出反应(这包括触摸并按住以进行剪切、复制和粘贴)。但是,您必须记住在关闭时将其设置回“是”,UIPickerView但是您将无法UIPickerView再次访问。

The only moment when it fails is when the user starts by tapping and holding the UITextView, then you'd see cut copy and paste again for the first time. This is why you should always validate your inputs. This is the easiest I can think of. The other option was to use a UILabelfor read-only text but you miss a lot of great functionality from UITextView.

唯一失败的时刻是当用户通过点击并按住 开始时UITextView,您会第一次再次看到剪切复制和粘贴。这就是为什么您应该始终验证您的输入。这是我能想到的最简单的方法。另一种选择是将 aUILabel用于只读文本,但您错过了UITextView.