UITextView
の[コピー]、[切り取り]、[選択]、[すべて選択]機能は、画面を押したときにデフォルトで表示されます。しかし、私のプロジェクトでは、UITextField
は読み取り専用です。この機能は必要ありません。この機能を無効にする方法を教えてください。
ペーストボード操作を無効にする最も簡単な方法は、許可しないアクションに対してUITextView
を返すcanPerformAction:withSender:
メソッドをオーバーライドするNO
のサブクラスを作成することです。
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(paste:))
return NO;
return [super canPerformAction:action withSender:sender];
}
IResponder も参照してください
UITextViewをサブクラス化し、canBecomeFirstResponderを上書きします。
- (BOOL)canBecomeFirstResponder {
return NO;
}
これは編集不可のUITextViewにのみ適用されることに注意してください!編集可能なものでテストしていない...
アプリケーションのallUITextView
で切り取り/コピー/貼り付けを無効にする場合は、categoryと:
@implementation UITextView (DisableCopyPaste)
- (BOOL)canBecomeFirstResponder
{
return NO;
}
@end
サブクラスを保存します... :-)
これは私にとって最高の実用的なソリューションでした:
UIView *overlay = [[UIView alloc] init];
[overlay setFrame:CGRectMake(0, 0, myTextView.contentSize.width, myTextView.contentSize.height)];
[myTextView addSubview:overlay];
[overlay release];
UITextViewをスクロールする必要がない場合、サブクラス化を伴わない最も簡単なソリューションは、テキストビューのユーザー操作を無効にすることです。
textField.userInteractionEnabled = NO;
@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
Swift 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;
}
IOS 7以降、UITextViewにプロパティがあります。
@property(nonatomic,getter=isSelectable) BOOL selectable;
これにより、ビューでテキストを選択できなくなります。私に最適です。
キーボードをaに置き換えたい場合、UIPicker
をinputView
として(もちろん、ツールバーをinputAccesotyView
として)、この回避策が役立つかもしれません。 ..
textFieldShouldBeginEditing:
textField.userInteractionEnabled = NO;
UIPickerView
を閉じようとしているときに、YESに設定します。これを行うことで、UITextField
をタップし、UIPickerView
から選択するオプションを表示できるようになります。現時点では、UITextField
は実際には反応しません。任意のタッチイベント(これには、カット、コピー、およびペーストのタッチアンドホールドが含まれます)。ただし、UIPickerView
を閉じるときは必ずYESに戻す必要がありますが、UIPickerView
に再度アクセスすることはできません。
失敗するのは、ユーザーがUITextView
をタップして保持することから始めたときだけです。その後、コピーの切り取りと貼り付けが初めて表示されます。このため、常に入力を検証する必要があります。これは私が考えることができる最も簡単です。もう1つのオプションは、読み取り専用テキストにUILabel
を使用することでしたが、UITextView
の優れた機能の多くが見逃されます。
サブクラスUITextView-Swift 4.0
override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return false
}
UITextField
のポップアップを無効にする場合は、このUITextFieldDelegate
メソッドを試してisUserInteractionEnabled
を切り替えます。
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
textField.isUserInteractionEnabled = false
return true
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
textField.isUserInteractionEnabled = true
return true
}
これは私のために働いた。 textViewでresignFirstResponderを呼び出していることを確認してください
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
[self.textView resignFirstResponder];
return NO;
}
有効な答えを提供しました here テキスト選択+拡大鏡を無効にし、有効なクリック可能なリンクを維持します:
かなり長い間試してみましたが、UITextViewサブクラスでaddGestureRecognizerをオーバーライドすることで、テキストの選択、拡大、およびデータ検出(リンクをクリック可能など)を停止し、UILongPressGestureRecognizerのみがタッチ終了を遅延できるようにしました。
UIUnselectableTextView.m
-(void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
if([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] && gestureRecognizer.delaysTouchesEnded)
{
[super addGestureRecognizer:gestureRecognizer];
}
}
Swiftの場合、次のように変更されます。
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でこれを行う方法です:
コピー、貼り付け、切り取り機能を無効にするには、サブクラスを作成し、次をオーバーライドします。
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];
}
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
これを行うには、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)
}
UITextViewには、必要な処理を行う2つのプロパティがあります:isSelectableおよびisEditable。
IsEditableをfalseに設定すると、ユーザーはテキストを編集できなくなり、isSelectableをfalseに設定すると、ユーザーがtextView内のテキストを選択できなくなるため、アクションメニューが表示されなくなります。
(Swift)メニューオプションや虫眼鏡のない基本的なテキストフィールドのみが必要な場合は、gestureRecognizerShouldBeginにfalseを返すUITextFieldのサブクラスを作成します。
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()
UITextView
のサブクラス化と- (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
のオーバーライドは、不要なアクションを無効にする別の可能性です。
gestureRecognizer
-オブジェクトのクラスを使用して、アクションを追加するかどうかを決定します。
次のようなカテゴリを作成できます。
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