简体   繁体   中英

Disable UITextField editing but still accept touch - Swift 3

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?

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

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

在此输入图像描述

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
    }

}

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
}

}

Additionally you can create a subclass of a UITextField and implement the methods below:

import UIKit

class MyCustomTextField: UITextField {

    override func caretRect(for position: UITextPosition) -> CGRect {
        return CGRect.zero
    }

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

        if action == #selector(copy) || action == #selector(cut) || action == #selector(paste){
            return false
        }
        else {
            return super.canPerformAction(action, withSender: sender)
        }
    }
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM