Функция UITextView
Копировать, вырезать, выбрать, выбрать все отображается по умолчанию, когда я нажимаю на экран. Но в моем проекте UITextField
доступен только для чтения. Я не требую этой функции. Скажите, пожалуйста, как отключить эту функцию.
Как отключить Копировать, Вырезать, Выбрать, Выбрать все в UITextView
Ответ 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];
Ответ 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