Как отключить редактирование UITextField, но все же принять прикосновение?

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

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

Что я могу сделать для его достижения?

Ответ 1

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

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

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

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

Ответ 2

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

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

self.textfield.delegate=self;

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

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

Вот оно!

Ответ 3

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

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

Ответ 4

Перевести ответ Ник на быстрый:

P/S: вернуть false = > текстовые поля не могут вводиться, редактировать с клавиатуры. Он просто может установить текст по коду. EX: textField.text = "My String Here"

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

Ответ 5

В Swift:

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

Ответ 6

Просто разместите UIButton точно по всему UITextField без текста метки, который делает его "невидимым". Эта кнопка может принимать и делегировать штрихи вместо текстового поля, и содержимое TextField все еще видно.

Ответ 7

Для альтернативы, которая обрабатывает UIPickerView и таблицы действий, checkout ActionSheetPicker

https://github.com/TimCinel/ActionSheetPicker

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

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

Ответ 8

Я использовал решение, предоставленное 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
    }

}

Ответ 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
   }
}

Ответ 10

Это обходное решение работает. Поместите прозрачный 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];
}

Ответ 11

Сделайте ваш inputView представленным скрытым текстовым полем, которое также изменит текст представленного и отключенного.

Ответ 12

Чтобы предотвратить редактирование 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
}

Ответ 13

Я использовал:

[self.textField setEnabled:NO];

и его работа отлично

Ответ 14

Это сработало для меня [textview setEditable:NO]; Вышеупомянутые ответы являются чрезмерно сложными.