Как отключить Копировать, Вырезать, Выбрать, Выбрать все в UITextView

Функция UITextView Копировать, вырезать, выбрать, выбрать все отображается по умолчанию, когда я нажимаю на экран. Но в моем проекте UITextField доступен только для чтения. Я не требую этой функции. Скажите, пожалуйста, как отключить эту функцию.

Ответ 1

Самый простой способ отключить операции UITextView - это создать подкласс UITextView который переопределяет canPerformAction:withSender: метод для возврата NO для действий, которые вы не хотите разрешать:

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

Также см. UIResponder

Ответ 2

Подкласс UITextView и перезапись canBecomeFirstResponder:

- (BOOL)canBecomeFirstResponder {
    return NO;
}

Обратите внимание, что это относится только к редактируемым UITextViews! Не проверял его на редактируемые...

Ответ 3

Если вы хотите отключить вырезание/копирование/вставку на все UITextView вашего приложения, вы можете использовать категорию с:

@implementation UITextView (DisableCopyPaste)

- (BOOL)canBecomeFirstResponder
{
    return NO;
}

@end

Сохраняет подклассы...: -)

Ответ 4

Это лучшее для меня решение:

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

Ответ 5

Если вам не нужно прокручивать UITextView, то самым простым решением, которое не связано с подклассификацией, является просто отключить взаимодействие пользователя для текстового представления:

textField.userInteractionEnabled = NO;

Ответ 6

Ответ @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)
    }

}

Ответ 7

Самый простой способ - создать подкласс UITextView, который переопределяет canPerformAction: withSender:

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

Ответ 8

Когда я возвращаю NO в canPerformAction на iOS 7, я получаю много ошибок, подобных этому:

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

Трюк состоит в том, чтобы скрыть контроллер меню в следующем цикле в главной очереди (сразу после его отображения).

Ответ 9

Это самый простой способ отключить все меню выбора/копирования/вставки в UITextView

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

Ответ 10

Так как iOS 7 есть свойство в UITextView:

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

Это позволяет просматривать варианты текста. Отлично работает для меня.

Ответ 11

Если вы хотите заменить клавиатуру a, допустим, UIPicker как inputView (с панелью инструментов, как inputAccesotyView), тогда это обходное решение может помочь...

  • Внедрить textFieldShouldBeginEditing:
  • внутри класть textField.userInteractionEnabled = NO;
  • Затем, когда вы собираетесь закрыть UIPickerView, установите для него значение YES.

Посредством этого вы можете нажать UITextField и показать опции, которые можно выбрать из UIPickerView, в это время ваш UITextField, действительно, не будет реагировать на какое-либо событие касания (это включает в себя касание и удержание для вырезания, копирования и вставки). Тем не менее, вам нужно будет помнить, чтобы вернуть его к YES, когда вы закрываете свой UIPickerView, однако вы больше не сможете получить доступ к своему UIPickerView.

Единственный момент, когда он терпит неудачу, - это когда пользователь начинает, нажимая и удерживая UITextView, то вы увидите вырезать копию и вставить снова в первый раз. Вот почему вы всегда должны проверять свои входы. Это самый легкий, о котором я могу думать. Другой вариант состоял в том, чтобы использовать текст UILabel только для чтения, но вы пропустили множество отличных функций от UITextView.

Ответ 12

Подкласс UITextView - swift 4.0

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

Ответ 13

Это сработало для меня. Убедитесь, что вы вызываете resignFirstResponder в textView

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

Ответ 14

Я предоставил рабочий ответ здесь, чтобы отключить выделение текста + лупу, поддерживая кликируемые ссылки Надеюсь, что это поможет:

По прошествии довольно долгого времени мне удалось остановить выбор текста, увеличить и сохранить обнаружение данных (ссылки, доступные по клику и т.д.), переопределив addGestureRecognizer в подклассе UITextView, разрешив только задержку касания UILongPressGestureRecognizer:

UIUnselectableTextView.m

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

Ответ 15

Это можно сделать легко в раскадровке (Xcode 6). Просто снимите флажок "Редактировать и выбрать в инспекторе атрибутов". Вы все еще можете прокручивать текстовое представление. введите описание изображения здесь

Ответ 16

Для Swift 3 он изменился на:

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

Ответ 17

Я сделал это. На моем UITextView я легко отключил функцию вырезания, копирования, выбора и т.д.

Я разместил a 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;
        }

    }
}

и это сработало для меня. Спасибо.

Ответ 18

Swift

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.

Ответ 19

Вы можете исправить это в своем раскадровке, сняв флажок:

введите описание изображения здесь

Или вы можете запрограммировать так:

textView.selectable = false
textView.editable = false

Ответ 20

Этот метод полностью отключит меню Выбрать, Выбрать все, Вставить. Если вы все еще получаете какое-то другое действие, просто добавьте его в условие 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];
    }

Ответ 21

Если вы хотите отключить всплывающее окно для UITextField попробуйте этот метод UITextFieldDelegate для переключения isUserInteractionEnabled.

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

Ответ 22

Вы можете просто создать такую ​​категорию:

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

Ответ 23

Подклассификация UITextView и переопределение - (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer - это еще одна возможность отключить нежелательные действия.

Используйте класс объекта gestureRecognizer, чтобы решить, нужно ли добавлять действие или нет.

Ответ 24

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

Ответ 25

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

Ответ 26

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

Ответ 27

Если вы хотите добавить настраиваемую опцию в свой UITextView, но отключите существующие функции, как это сделать на Swift 3:

Чтобы отключить копирование, вставить, вырезать funcionality, создайте подкласс и переопределите следующее:

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

    }

Ответ 28

Используйте 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

введите описание изображения здесь