Как отключить редактирование UITextField, но все еще принимать касание? - PullRequest
98 голосов
/ 02 февраля 2012

Я делаю UITextField с UIPickerView как inputView.Все хорошо, за исключением того, что я могу редактировать, копировать, вставлять, вырезать и выделять текст, а я этого не хочу.Только сборщик должен изменять текстовое поле.

Я узнал, что я могу отключить редактирование, установив setEnabled или setUserInteractionEnabled в NO.Хорошо, но TextField перестает реагировать на прикосновения, а средство выбора не отображается.

Что я могу сделать, чтобы добиться этого?

Ответы [ 14 ]

122 голосов
/ 02 февраля 2012

Используя делегат текстового поля, есть метод

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

Возврат NO из этого, и любая попытка пользователя отредактировать текст будет отклонена.

Таким образом, вы можете оставитьполе включено, но все равно не позволяет людям вставлять в него текст.

16 голосов
/ 24 июля 2015

Переведите ответ Ник на swift:

P / S: Возврат false => текстовые поля не могут быть введены, редактирование осуществляется с клавиатуры. Он просто может установить текст по code.EX: textField.text = "Моя строка здесь"

override func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    return false
}
16 голосов
/ 08 июля 2013

Это будет самое простое из всех:

в viewDidLoad: (установите делегат только для текстовых полей, которые не должны редактироваться.

self.textfield.delegate=self;

и вставьте эту делегатскую функцию:

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

Вот так!

7 голосов
/ 10 октября 2017

В быстром 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 голосов
/ 20 июня 2016

В Swift:

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    questionField.resignFirstResponder();
    // Additional code here
    return false
}
7 голосов
/ 02 февраля 2012

Было бы более элегантно создать собственный подкласс UITextField, который возвращает NO для всех вызовов canPerformAction:withSender: (или, по крайней мере, где action равно @selector(cut) или @selector(paste)), как описано здесь .

Кроме того, я бы также реализовал - (BOOL) textField: (UITextField *) textField shouldChangeCharactersInRange: (NSRange) диапазон replaceString: (NSString *) строка согласно предложению Ника вчтобы отключить ввод текста с клавиатуры Bluetooth.

6 голосов
/ 26 января 2015

Просто поместите UIButton точно по всему UITextField без текста Label, что делает его «невидимым».Эта кнопка может получать и делегировать касания вместо текстового поля, а содержимое текстового поля все еще отображается.

3 голосов
/ 03 мая 2015

Я использовал решение, предоставленное 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 голос
/ 18 июня 2015

Чтобы предотвратить редактирование UITextField при использовании UIPickerView для выбора значений (в 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
}
1 голос
/ 02 апреля 2014

Для альтернативы, которая обрабатывает UIPickerView и Action Sheets, извлеките ActionSheetPicker

https://github.com/TimCinel/ActionSheetPicker

Включены кокосопод.Он обрабатывает все кнопки отмены и завершения на листе действий.Примеры в рамках примера проекта великолепны.Я выбираю ActionSheetStringPicker, который легко обрабатывает только параметры, основанные на строках, но API может обрабатывать практически все, что я могу придумать.

Я изначально начал решение, очень похожее на ответ с пометкой галочкой, но наткнулся на этот проект и взялПримерно 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.
}
...