UITextView의 복사, 잘라 내기, 선택은 모두 선택 기능은 I가 화면에 눌러 기본적으로 표시됩니다. 그러나 내 프로젝트에서는 UITextField읽기 전용입니다. 이 기능이 필요하지 않습니다. 이 기능을 비활성화하는 방법을 알려주십시오.
UITextView의 복사, 잘라 내기, 선택은 모두 선택 기능은 I가 화면에 눌러 기본적으로 표시됩니다. 그러나 내 프로젝트에서는 UITextField읽기 전용입니다. 이 기능이 필요하지 않습니다. 이 기능을 비활성화하는 방법을 알려주십시오.
답변:
대지 작업을 비활성화하는 가장 쉬운 방법은 허용하지 않으려는 작업에 대해 반환 UITextView할 canPerformAction:withSender:메서드를 재정의 하는의 하위 클래스를 만드는 것입니다 NO.
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(paste:))
return NO;
return [super canPerformAction:action withSender:sender];
}
UIResponder 참조
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { return NO; }-모든 옵션 차단
모든 UITextView 응용 프로그램 에서 잘라 내기 / 복사 / 붙여 넣기를 비활성화 하려면 다음 과 함께 범주 를 사용할 수 있습니다 .
@implementation UITextView (DisableCopyPaste)
- (BOOL)canBecomeFirstResponder
{
return NO;
}
@end
그것은 서브 클래 싱을 저장합니다 ... :-)
UITextView예를 들어 편집 가능하고 터치를 얻을 때 예상대로 작동 하지 않도록합니다 . 무시할 것이 많다 canPerformAction:withSender:. 그것이 프로토콜의 목적입니다.
이것은 나에게 가장 적합한 솔루션이었습니다.
UIView *overlay = [[UIView alloc] init];
[overlay setFrame:CGRectMake(0, 0, myTextView.contentSize.width, myTextView.contentSize.height)];
[myTextView addSubview:overlay];
[overlay release];
@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
스위프트 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)
}
}
스크롤하는 데 UITextView가 필요하지 않은 경우 하위 클래스를 포함하지 않는 가장 간단한 솔루션은 단순히 텍스트보기에 대한 사용자 상호 작용을 비활성화하는 것입니다.
textField.userInteractionEnabled = NO;
가장 쉬운 방법은 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;
}
키보드를 a로 교체하려는 UIPicker경우 inputView(물론 도구 모음이으로 inputAccesotyView)이 해결 방법이 도움이 될 수 있습니다.
textFieldShouldBeginEditing:textField.userInteractionEnabled = NO;UIPickerViewYES로 설정하십시오.이렇게하면을 탭 UITextField하고에서 선택할 수있는 옵션을 표시 할 수 있습니다 UIPickerView. 현재로서는 UITextField터치 이벤트에 반응하지 않을 것입니다 (여기에는 잘라 내기, 복사 및 붙여 넣기를위한 길게 터치 포함). 그러나 닫을 때 다시 YES로 설정해야 UIPickerView하지만 UIPickerView다시 액세스 할 수 없습니다 .
실패하는 유일한 순간은 사용자가을 길게 눌러 시작 UITextView하면 처음으로 잘라 내기 복사 및 붙여 넣기가 표시됩니다. 이것이 항상 입력의 유효성을 검사해야하는 이유입니다. 이것이 제가 생각할 수있는 가장 쉬운 방법입니다. 다른 옵션은 UILabel읽기 전용 텍스트 에를 사용하는 것이었지만 UITextView.
팝업을 비활성화하려면 UITextField이 UITextFieldDelegate방법을 사용하여 isUserInteractionEnabled.
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
textField.isUserInteractionEnabled = false
return true
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
textField.isUserInteractionEnabled = true
return true
}
여기 에 텍스트 선택 + 돋보기를 비활성화하고 클릭 가능한 링크를 활성화하는 데 도움이 되는 작업 답변을 제공했습니다 .
오랜 시간 동안 시도한 끝에 UITextView 하위 클래스에서 addGestureRecognizer를 재정 의하여 터치 종료를 지연시키는 UILongPressGestureRecognizer 만 허용하여 텍스트 선택, 확대 및 데이터 감지 (링크 클릭 가능 등)를 중지 할 수있었습니다.
UIUnselectableTextView.m
-(void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
if([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] && gestureRecognizer.delaysTouchesEnded)
{
[super addGestureRecognizer:gestureRecognizer];
}
}
들어 스위프트 3 그것은 할 변경된 :
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 3 에서 수행하는 방법입니다 .
복사, 붙여 넣기, 잘라 내기 기능을 비활성화하려면 하위 클래스를 만들고 다음을 재정의합니다.
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];
}
다음과 같이 카테고리를 만들 수 있습니다.
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
서브 클래 싱 UITextView및 재정의 - (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer는 원하지 않는 작업을 비활성화 할 수있는 또 다른 가능성입니다.
gestureRecognizer-object 의 클래스를 사용하여 조치를 추가해야하는지 여부를 결정하십시오.
(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()
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)}
스위프트 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)
}
참조 용 샘플 코드를 찾으십시오.
override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(copy(_:)) || action == #selector(paste(_:)) || action == #selector(UIResponderStandardEditActions.paste(_:)) ||
action == #selector(replace(_:withText:)) ||
action == #selector(UIResponderStandardEditActions.cut(_:)) ||
action == #selector(UIResponderStandardEditActions.select(_:)) ||
action == #selector(UIResponderStandardEditActions.selectAll(_:)) ||
action == #selector(UIResponderStandardEditActions.delete(_:)) ||
action == #selector(UIResponderStandardEditActions.makeTextWritingDirectionLeftToRight(_:)) ||
action == #selector(UIResponderStandardEditActions.makeTextWritingDirectionRightToLeft(_:)) ||
action == #selector(UIResponderStandardEditActions.toggleBoldface(_:)) ||
action == #selector(UIResponderStandardEditActions.toggleItalics(_:)) ||
action == #selector(UIResponderStandardEditActions.toggleUnderline(_:)) ||
action == #selector(UIResponderStandardEditActions.increaseSize(_:)) ||
action == #selector(UIResponderStandardEditActions.decreaseSize(_:))
{
return false
}
return true
}
사용 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로 클래스 새 클래스 추가