UITextField 편집을 비활성화하지만 여전히 터치를 허용하는 방법은 무엇입니까?


107

나는 as UITextField를 가지고 UIPickerView있습니다 inputView. 복사, 붙여 넣기, 잘라 내기 및 텍스트 선택으로 편집 할 수 있다는 점을 제외하면 모두 좋습니다. 선택 도구 만 텍스트 필드를 수정해야합니다.

setEnabled또는 setUserInteractionEnabled을 설정 하여 편집을 비활성화 할 수 있음을 배웠습니다 NO. 좋습니다.하지만 TextField가 터치에 응답하지 않고 선택기가 표시되지 않습니다.

그것을 달성하기 위해 무엇을 할 수 있습니까?

답변:


131

텍스트 필드 대리자를 사용하는 방법이 있습니다.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

여기서 NO를 반환하면 사용자가 텍스트를 편집하려는 모든 시도가 거부됩니다.

이렇게하면 필드를 활성화 된 상태로 둘 수 있지만 여전히 사람들이 텍스트를 붙여 넣는 것을 방지 할 수 있습니다.


4
여전히 터치에 응답하려면 "내부 터치 업"이 아니라 "터치 다운"에 응답하십시오. 그렇지 않으면 이벤트가 호출되지 않습니다.
radven

@NickLockwood textField가 첫 번째 응답자가 될 수 있지만 사용자 상호 작용을 비활성화하고 캐럿을 숨길 수있는 방법이 있습니까?
onmyway133 2014

1
@entropy 사용자가 복사 할 수 있도록 콘텐츠를 선택할 수 있기를 원한다고 가정합니다. UITextField를 하위 클래스로 지정하면 거의 모든 동작을 재정의 할 수 있습니다. 예를 들어 사용자가 터치 할 때마다 필드가 항상 모두를 선택하도록 강제 할 수 있으므로 캐럿을 효과적으로 숨길 수 있습니다.
Nick Lockwood 2014

1
@LoryLory 동일합니다. 대신 위임 메서드에 Swift 구문을 사용하십시오.
Nick Lockwood 2015 년

5
더 정확하게 필요한 경우 우리는 "textFieldShouldBeginEditing"를 사용할 수 있습니다
나빈 산을

22

Nick 의 대답 을 신속하게 번역하십시오 .

P / S : false => 텍스트 필드를 입력 할 수 없으며 키보드로 편집 할 수 없습니다. code.EX로 텍스트를 설정할 수 있습니다. textField.text = "My String Here"

override func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    return false
}

3
이것은 나를 위해 작동하지 않습니다. 확대 / 축소가 나타나고 iOS 잘라 내기 / 복사 / 붙여 넣기 메뉴가 나타날 때까지 텍스트 필드를 길게 클릭하면 텍스트를 변경할 수 있습니다.
RowanPD

2
신속한 4 :`func textField (_ textField : UITextField, shouldChangeCharactersIn 범위 : NSRange, replacementString string : String)-> Bool {return false}`
lionello

16

이것은 가장 간단합니다.

in viewDidLoad :( 편집 불가능한 텍스트 필드에 대해서만 대리자를 설정합니다.

self.textfield.delegate=self;

다음 대리자 함수를 삽입하십시오.

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
return NO;
}

그게 다야!


27
이렇게하면 선택기가 표시되지 않으므로 설명 된 문제가 해결되지 않습니다
Martin Lockett 2013

6
@MartinLockett UIPickerView해당 대리자 메서드에서 동작 을 트리거하면 잘 작동합니다.
Albert Bori 2015 년

9

신속한 3+ :

class MyViewController: UIViewController, UITextFieldDelegate {

   override func viewDidLoad() {
      self.myTextField.delegate     = self
   }

   func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
      if textField == myTextField {
         // code which you want to execute when the user touch myTextField
      }
      return false
   }
}

7

의 사용자 지정 하위 클래스 만들기 위해 더 우아한 것 UITextField그 반환 NO모든 통화를 canPerformAction:withSender:(여기서 또는 적어도 action이다 @selector(cut)@selector(paste))와 같이, 여기 .

또한 Bluetooth 키보드에서 텍스트 입력을 비활성화하기 위해 Nick의 제안에 따라 (BOOL) textField : (UITextField *) textField shouldChangeCharactersInRange : (NSRange) range replacementString : (NSString *) string을 구현합니다.


제 삶을 위해 어떻게해야하는지 알 수 없습니다. 하위 클래스 canPerformActionshouldChangeCharactersInRange메서드는 호출되지 않습니다.
Nestor

7

레이블 텍스트없이 전체 UITextField 위에 UIButton을 정확히 배치하면 "보이지 않게"됩니다. 이 버튼은 Textfield 대신 터치를 수신하고 위임 할 수 있으며 TextField의 내용은 계속 표시됩니다.


7

Swift에서 :

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    questionField.resignFirstResponder();
    // Additional code here
    return false
}

3

MrMage에서 제공하는 솔루션을 사용했습니다. 내가 추가 할 유일한 것은 UITextView를 첫 번째 응답자로 사임해야한다는 것입니다. 그렇지 않으면 선택한 텍스트에 갇혀 있습니다.

내 빠른 코드는 다음과 같습니다.

class TouchableTextView : UITextView {

    override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
        self.resignFirstResponder()
        return false
    }

    override func shouldChangeTextInRange(range: UITextRange, replacementText text: String) -> Bool {
        self.resignFirstResponder()
        return false
    }

}

1

UIPickerView 및 Action Sheets를 처리하는 대안은 ActionSheetPicker를 확인하십시오.

https://github.com/TimCinel/ActionSheetPicker

코코아 포드가 활성화되었습니다. 작업 시트의 모든 취소 및 완료 버튼을 처리합니다. 샘플 프로젝트의 예제는 훌륭합니다. String 기반 옵션 만 쉽게 처리하는 ActionSheetStringPicker를 선택하지만 API는 내가 생각할 수있는 대부분의 모든 것을 처리 할 수 ​​있습니다.

나는 원래 체크 표시가 된 답변과 매우 유사한 솔루션을 시작했지만이 프로젝트를 우연히 발견하고 cocopods 사용을 포함하여 사용하기 위해 내 앱에 통합하는 데 약 20 분이 걸렸습니다 : ActionSheetPicker (~> 0.0)

도움이 되었기를 바랍니다.

git 프로젝트를 다운로드하고 다음 클래스를 살펴보십시오.

  • ActionSheetPickerViewController.m
  • ActionSheetPickerCustomPickerDelegate.h

여기에 내가 추가 한 거의 대부분의 코드와 * .h 가져 오기가 있습니다.

- (IBAction)gymTouched:(id)sender {
      NSLog(@"gym touched");

      [ActionSheetStringPicker showPickerWithTitle:@"Select a Gym" rows:self.locations initialSelection:self.selectedIndex target:self successAction:@selector(gymWasSelected:element:) cancelAction:@selector(actionPickerCancelled:) origin:sender];
 }


- (void)actionPickerCancelled:(id)sender {
    NSLog(@"Delegate has been informed that ActionSheetPicker was cancelled");
}


- (void)gymWasSelected:(NSNumber *)selectedIndex element:(id)element {
    self.selectedIndex = [selectedIndex intValue];

    //may have originated from textField or barButtonItem, use an IBOutlet instead of element
    self.txtGym.text = [self.locations objectAtIndex:self.selectedIndex];
}


-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    return NO;  // Hide both keyboard and blinking cursor.
}

포드의 업데이트 된 버전이 여기에 있습니다. github.com/skywinder/ActionSheetPicker-3.0
Nick N

1

값을 선택하기 위해 UIPickerView를 사용하는 동안 UITextField의 편집을 방지하려면 (Swift에서) :

self.txtTransDate = self.makeTextField(self.transDate, placeHolder: "Specify Date")
self.txtTransDate?.addTarget(self, action: "txtTransDateEditing:", forControlEvents: UIControlEvents.EditingDidBegin)

func makeTextField(text: String?, placeHolder: String) -> UITextField {
    var textField = UITextField(frame: CGRect(x: 140, y: 0, width: 220.00, height: 40.00));
    textField.placeholder = placeHolder
    textField.text = text
    textField.borderStyle = UITextBorderStyle.Line
    textField.secureTextEntry = false;
    textField.delegate = self
    return textField
}


func txtTransDateEditing(sender: UITextField) {
    var datePickerView:UIDatePicker = UIDatePicker()
    datePickerView.datePickerMode = UIDatePickerMode.Date
    sender.inputView = datePickerView
    datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}

func datePickerValueChanged(sender: UIDatePicker) {
    var dateformatter = NSDateFormatter()
    dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
    self.txtTransDate!.text = dateformatter.stringFromDate(sender.date)
}

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool  {
    self.resignFirstResponder()
    return false
}

0

이 해결 방법이 작동합니다. 텍스트 필드 위에 투명한 UIView를 배치하고 다음 코드를 구현합니다.

- (void)viewDidLoad
{
 [super viewDidLoad];

   UILongPressGestureRecognizer *press = [[UILongPressGestureRecognizer alloc]             initWithTarget:self action:@selector(longPress)];
[transparentView addGestureRecognizer:press];
 [press release];
  press = nil;
}

-(void)longPress
{
   txtField.userInteractionEnabled = NO;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   txtField.userInteractionEnabled = YES;
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
  [txtField becomeFirstResponder];
}

1
간단한 투명 UIButton + touchUpInside를 사용하지 않고 대신 UIView + 제스처를 선택한 이유가 혼란 스럽습니다.
Chen Li Yong

0

귀하의 inputView가 숨겨진 텍스트 필드로 표시되도록 만드십시오.이 텍스트 필드는 표시되고 비활성화 된 텍스트도 변경합니다.


-5

나는 사용했다 :

[self.textField setEnabled:NO];

그리고 그것의 작동


-7

이것은 나를 위해 일했습니다 [textview setEditable:NO]; . 위의 답변은 상황을 지나치게 복잡하게 만들고 있습니다.


1
OP는 "setEnabled 또는 setUserInteractionEnabled : NO를 NO로 설정하여 편집을 비활성화 할 수 있다는 것을 배웠습니다. 그래도 TextField가 터치에 응답하지 않고 선택기가 표시되지 않습니다." 귀하의 답변은 원하는 결과가 아닌 모든 이벤트를 중지합니다.
maninvan

@Tolgab 은이 OP에 대한 관련 솔루션이 아닙니다!
Anurag Sharma
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.