Как отключить копирование, вырезание, выделение, выделение всего в UITextView - PullRequest
102 голосов
/ 15 сентября 2009

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

Ответы [ 28 ]

101 голосов
/ 15 сентября 2009

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

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

Также см. UIResponder

67 голосов
/ 06 августа 2010

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

- (BOOL)canBecomeFirstResponder {
    return NO;
}

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

30 голосов
/ 04 ноября 2011

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

@implementation UITextView (DisableCopyPaste)

- (BOOL)canBecomeFirstResponder
{
    return NO;
}

@end

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

29 голосов
/ 27 марта 2012

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

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

от: https://stackoverflow.com/a/5704584/1293949

20 голосов
/ 09 ноября 2010

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

textField.userInteractionEnabled = NO;
18 голосов
/ 20 ноября 2014

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

}
15 голосов
/ 24 апреля 2010

Самый простой способ - создать подкласс 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;
}
13 голосов
/ 04 марта 2014

Когда я возвращаю 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];
}

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

10 голосов
/ 10 ноября 2009

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

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{    
    [UIMenuController sharedMenuController].menuVisible = NO;
    return NO;    
}
4 голосов
/ 29 мая 2014

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...