How to disable UITextField editing but still accept touch?

I'm making a UITextField that has a UIPickerView as inputView. Its all good, except that I can edit by copy, paste, cut and select text, and I don't want it. Only the Picker should modify text field.

I've learned that I can disable editing by setting setEnabled or setUserInteractionEnabled to NO. Ok, but the TextField stop responding to touching and the picker don't show up.

What can I do to achieve it?


Solution 1:

Using the textfield delegate, there's a method

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

Return NO from this, and any attempt by the user to edit the text will be rejected.

That way you can leave the field enabled but still prevent people pasting text into it.

Solution 2:

Translate the answer of Nick to swift:

P/S: Return false => the textfields cannot input, edit by the keyboard. It just can set text by code.EX: textField.text = "My String Here"

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

Solution 3:

This would be the simplest of all:

in viewDidLoad:(set the delegate only for textfields which should not be editable.

self.textfield.delegate=self;

and insert this delegate function:

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

Thats it!

Solution 4:

In swift 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
   }
}

Solution 5:

Simply place a UIButton exactly over the entire UITextField with no Label-text which makes it "invisible". This button can receive and delegate touches instead of the Textfield and the content of the TextField is still visible.