web-dev-qa-db-ja.com

UITextViewでコピー、切り取り、選択、すべて選択を無効にする方法

UITextViewの[コピー]、[切り取り]、[選択]、[すべて選択]機能は、画面を押したときにデフォルトで表示されます。しかし、私のプロジェクトでは、UITextFieldは読み取り専用です。この機能は必要ありません。この機能を無効にする方法を教えてください。

103
Aishwarya

ペーストボード操作を無効にする最も簡単な方法は、許可しないアクションに対してUITextViewを返すcanPerformAction:withSender:メソッドをオーバーライドするNOのサブクラスを作成することです。

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

IResponder も参照してください

102
rpetrich

UITextViewをサブクラス化し、canBecomeFirstResponderを上書きします。

- (BOOL)canBecomeFirstResponder {
    return NO;
}

これは編集不可のUITextViewにのみ適用されることに注意してください!編集可能なものでテストしていない...

67
iCoder

アプリケーションのallUITextViewで切り取り/コピー/貼り付けを無効にする場合は、categoryと:

@implementation UITextView (DisableCopyPaste)

- (BOOL)canBecomeFirstResponder
{
    return NO;
}

@end

サブクラスを保存します... :-)

30
Damien Debin

これは私にとって最高の実用的なソリューションでした:

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

29
Saraiva Alcides

UITextViewをスクロールする必要がない場合、サブクラス化を伴わない最も簡単なソリューションは、テキストビューのユーザー操作を無効にすることです。

textField.userInteractionEnabled = NO;
20
Luke Redpath

@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)
    }

}
18
pinch

最も簡単な方法は、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;
}
15
haiLong

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];
}

トリックは、メインキューの次のサイクル(表示された直後)でメニューコントローラーを非表示にすることです。

13
Adam Wallner

これは、UITextViewの選択/コピー/貼り付けメニュー全体を無効にする最も簡単な方法です。

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

IOS 7以降、UITextViewにプロパティがあります。

 @property(nonatomic,getter=isSelectable) BOOL selectable;

これにより、ビューでテキストを選択できなくなります。私に最適です。

4
Epaga

キーボードをaに置き換えたい場合、UIPickerinputViewとして(もちろん、ツールバーをinputAccesotyViewとして)、この回避策が役立つかもしれません。 ..

  • 実装textFieldShouldBeginEditing:
  • 内部にtextField.userInteractionEnabled = NO;
  • 次に、UIPickerViewを閉じようとしているときに、YESに設定します。

これを行うことで、UITextFieldをタップし、UIPickerViewから選択するオプションを表示できるようになります。現時点では、UITextFieldは実際には反応しません。任意のタッチイベント(これには、カット、コピー、およびペーストのタッチアンドホールドが含まれます)。ただし、UIPickerViewを閉じるときは必ずYESに戻す必要がありますが、UIPickerViewに再度アクセスすることはできません。

失敗するのは、ユーザーがUITextViewをタップして保持することから始めたときだけです。その後、コピーの切り取りと貼り付けが初めて表示されます。このため、常に入力を検証する必要があります。これは私が考えることができる最も簡単です。もう1つのオプションは、読み取り専用テキストにUILabelを使用することでしたが、UITextViewの優れた機能の多くが見逃されます。

4
rn3sto

サブクラスUITextView-Swift 4.0

     override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return false
    }
4
Manee ios

UITextFieldのポップアップを無効にする場合は、このUITextFieldDelegateメソッドを試してisUserInteractionEnabledを切り替えます。

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    textField.isUserInteractionEnabled = false
    return true
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
    textField.isUserInteractionEnabled = true
    return true
}
2
Jayesh Thanki

これは、ストーリーボード(Xcode 6)で簡単に実行できます。 [属性インスペクター]で[編集可能]および[選択可能]のチェックを外すだけです。テキストビューはスクロールできます。 enter image description here

2
Hari Kunwar

これは私のために働いた。 textViewでresignFirstResponderを呼び出していることを確認してください

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
  [self.textView resignFirstResponder];
  return NO;
}
2
verma

有効な答えを提供しました here テキスト選択+拡大鏡を無効にし、有効なクリック可能なリンクを維持します:

かなり長い間試してみましたが、UITextViewサブクラスでaddGestureRecognizerをオーバーライドすることで、テキストの選択、拡大、およびデータ検出(リンクをクリック可能など)を停止し、UILongPressGestureRecognizerのみがタッチ終了を遅延できるようにしました。

UIUnselectableTextView.m

-(void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
    if([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] && gestureRecognizer.delaysTouchesEnded)
    {
        [super addGestureRecognizer:gestureRecognizer];
    }
}
2
Thibaud David

Swiftの場合、次のように変更されます。

override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    return false
}
2
Andrey Gordeev

やった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;
        }

    }
}

そしてそれは私のために働いた。ありがとうございました。

1
user207221

これらのボックスのチェックを外すと、ストーリーボードでこれを修正できます。

enter image description here

または、次のようにプログラムで設定できます。

textView.selectable = false
textView.editable = false
1
Khuong

スイフト

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

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)")

    }
1
Sam Bing

このメソッドは、選択、すべて選択、貼り付けメニューを完全に無効にします。それでも他のアクションが発生する場合は、以下のように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];
    }
1
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)}
0
Nirav Ghori

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)
    }
0
Zaldy

UITextViewには、必要な処理を行う2つのプロパティがあります:isSelectableおよびisEditable

IsEditableをfalseに設定すると、ユーザーはテキストを編集できなくなり、isSelectableをfalseに設定すると、ユーザーがtextView内のテキストを選択できなくなるため、アクションメニューが表示されなくなります。

0
L. Davì

(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()
0
Krivvenz

UITextViewのサブクラス化と- (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizerのオーバーライドは、不要なアクションを無効にする別の可能性です。

gestureRecognizer-オブジェクトのクラスを使用して、アクションを追加するかどうかを決定します。

0
RhodanV5500

次のようなカテゴリを作成できます。

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
0
user2091319