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;
UIPickerView
YES로 설정하십시오.이렇게하면을 탭 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로 클래스 새 클래스 추가