Disable UITextField editing but still accept touch - Swift 3

10,856

Solution 1

To prevent the copy/paste menu appearing…

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    if dateTextField.isFirstResponder {
        DispatchQueue.main.async(execute: {
            (sender as? UIMenuController)?.setMenuVisible(false, animated: false)
        })
        return false
    }

    return super.canPerformAction(action, withSender: sender)
}

And implement…

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    // show UIDatePicker
    return false
}

This hides the menu before it has a chance to appear

Solution 2

Use func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { retrun bool } in place of textFieldShouldBeginEditing.

class ViewController: UIViewController , UITextFieldDelegate {

    @IBOutlet weak var textField: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()

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

Create a New class with Name StopPasteAction.swift

import UIKit

class StopPasteAction: UITextField {

    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return false
    }
}

Add the class new class with you Curren textfield

enter image description here

Solution 3

You can addTarget to textField, and in the textField delegate method, disable the editing like below:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var tedtField: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()

        tedtField.delegate = self
        tedtField.addTarget(self, action: #selector(respondsToTf), for: .touchDown)
    }

    func respondsToTf()  {

        // 
        print("you can pop-up the data picker here")
    }

    // MARK: - textfield delegate
    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {

        return false
    }

}

Solution 4

swift 3:

class MyViewController: UIViewController, UITextFieldDelegate {

   @IBOutlet weak var myTextField           : UITextField!

   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

That's how I solve this problem

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var testTxf: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    testTxf.delegate = self
    let tap = UITapGestureRecognizer(target: self, action: #selector(testFunc))
    testTxf.addGestureRecognizer(tap)
    testTxf.isUserInteractionEnabled = true
}

@objc func testFunc() {
    print("tap")
}

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

}

Share:
10,856
user-unknown
Author by

user-unknown

Updated on June 04, 2022

Comments

  • user-unknown
    user-unknown almost 2 years

    I'm creating a UITextField that has a UIDatePicker as input. I don't want the textfield to be edited (copy, paste, cut and select text), but I only want to show UIDatePicker when users touch the UITextField and the chosen date will be displayed on UITextField.

    I've tried to disable editing by using isUserInteractionEnabled = false, but the TextField doesn't give me response when I touch it.

    What should I do to achieve it in Swift 3?

  • toddg
    toddg over 7 years
    Doesn't work for me. I can still do a long press in the UITextField and trigger the paste dialog.
  • Abhishek Sharma
    Abhishek Sharma over 7 years
    @toddg Please check the code on dropbox dropbox.com/s/84wb7k23wdlkazc/UItextDelagte.zip?dl=0 If work please let me know
  • toddg
    toddg over 7 years
    I don't need it that badly. PS I'm not the one that down voted this answer.
  • Mitch Downey
    Mitch Downey over 6 years
    Worked great for me. I didn't need the textFieldShouldBeingEditing part in Swift 3.
  • boog
    boog over 4 years
    could work, but have to show & hide datePicker by yourself