回答:
ペーストボード操作を無効にする最も簡単な方法は、許可したくないアクションに対して返すメソッドを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
のアプリケーションで切り取り/コピー/貼り付けを無効にする場合は、次のようにカテゴリを使用できます。
@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)
}
}
UITextViewをスクロールする必要がない場合、サブクラス化を含まない最も簡単なソリューションは、テキストビューのユーザー操作を無効にすることです。
textField.userInteractionEnabled = NO;
最も簡単な方法は、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
切り取りコピーと貼り付けが初めて表示されます。このため、常に入力を検証する必要があります。これは私が考えることができる最も簡単です。もう1つのオプションは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
}
私はここでテキスト選択+拡大鏡を無効にし、有効なクリック可能なリンクを維持するための実用的な答えを提供しました
かなり長い間試した後、UILongPressGestureRecognizerのみがタッチ終了を遅らせることを許可するUITextViewサブクラスでaddGestureRecognizerをオーバーライドすることで、テキストの選択、拡大、データ検出(リンクをクリック可能など)を維持することに成功しました。
UIUnselectableTextView.m
-(void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
if([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] && gestureRecognizer.delaysTouchesEnded)
{
[super addGestureRecognizer:gestureRecognizer];
}
}
スウィフト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のサブクラスを作成して、gestureRecognizerShouldBeginにfalseを返します。
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でクラスnew classを追加します