I would like to detect the touch action on a UITextField.
It seems the "Touch Up Inside" action is not fired by touching inside the textfield.
I would like to detect the touch action on a UITextField.
It seems the "Touch Up Inside" action is not fired by touching inside the textfield.
It seems "Touch Up Inside" is not enabled for UITextField, but "Touch Down" works.
So the solution is as follows:
Swift 4.x
myTextField.addTarget(self, action: #selector(myTargetFunction), for: .touchDown)
@objc func myTargetFunction(textField: UITextField) {
print("myTargetFunction")
}
Swift 3.x
myTextField.addTarget(self, action: #selector(myTargetFunction), for: UIControlEvents.touchDown)
@objc func myTargetFunction(textField: UITextField) {
print("myTargetFunction")
}
class ViewController: UIViewController, UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == myTextField {
print("You edit myTextField")
}
}
}
This is a delegate function.
here's Swfit:
and you don't need to use the "touchUpInside" just use the delegate methods like so:
Make your View controller a delegate:
class ViewController: UIViewController, UITextFieldDelegate{
func textFieldDidBeginEditing(textField: UITextField) -> Bool {
if textField == myTextField {
return true // myTextField was touched
}
}
Here's the other delegate methods:
protocol UITextFieldDelegate : NSObjectProtocol {
optional func textFieldShouldBeginEditing(textField: UITextField) -> Bool // return NO to disallow editing.
optional func textFieldDidBeginEditing(textField: UITextField) // became first responder
optional func textFieldShouldEndEditing(textField: UITextField) -> Bool // return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end
optional func textFieldDidEndEditing(textField: UITextField) // may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called
optional func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool // return NO to not change text
optional func textFieldShouldClear(textField: UITextField) -> Bool // called when clear button pressed. return NO to ignore (no notifications)
optional func textFieldShouldReturn(textField: UITextField) -> Bool // called when 'return' key pressed. return NO to ignore.
}
from swift docs:
struct UIControlEvents : RawOptionSetType {
init(_ rawValue: UInt)
init(rawValue: UInt)
static var TouchDown: UIControlEvents { get } // on all touch downs
static var TouchDownRepeat: UIControlEvents { get } // on multiple touchdowns (tap count > 1)
static var TouchDragInside: UIControlEvents { get }
static var TouchDragOutside: UIControlEvents { get }
static var TouchDragEnter: UIControlEvents { get }
static var TouchDragExit: UIControlEvents { get }
static var TouchUpInside: UIControlEvents { get }
static var TouchUpOutside: UIControlEvents { get }
static var TouchCancel: UIControlEvents { get }
static var ValueChanged: UIControlEvents { get } // sliders, etc.
static var EditingDidBegin: UIControlEvents { get } // UITextField
static var EditingChanged: UIControlEvents { get }
static var EditingDidEnd: UIControlEvents { get }
static var EditingDidEndOnExit: UIControlEvents { get } // 'return key' ending editing
static var AllTouchEvents: UIControlEvents { get } // for touch events
static var AllEditingEvents: UIControlEvents { get } // for UITextField
static var ApplicationReserved: UIControlEvents { get } // range available for application use
static var SystemReserved: UIControlEvents { get } // range reserved for internal framework use
static var AllEvents: UIControlEvents { get }
}
UITextField doesn't respond to "touchUpInside" see to the right side, you'll find it's acceptable control events
Update For Swift 3
Here is the code for Swift 3:
myTextField.addTarget(self, action: #selector(myTargetFunction), for: .touchDown)
This is the function:
func myTargetFunction() {
print("It works!")
}
I referred to the UIControlEvents documentation from Apple and came up with the following:
First add UITextFieldDelegate to your class then,
textBox.delegate = self
textBox.addTarget(self, action: #selector(TextBoxOn(_:)),for: .editingDidBegin)
textBox.addTarget(self, action: #selector(TextBoxOff(_:)),for: .editingDidEnd)
with the following functions:
func TextBoxOff(_ textField: UITextField) {
code
}
}
func TextBox(_ textField: UITextField) {
code
}
}
For Swift 3.1:
1) Create a gesture recognizer:
let textViewRecognizer = UITapGestureRecognizer()
2) Add a handler to the recognizer:
textViewRecognizer.addTarget(self, action: #selector(tappedTextView(_:)))
3) Add the recognizer to your text view:
textView.addGestureRecognizer(textViewRecognizer)
4) Add the handler to your class:
func tappedTextView(_ sender: UITapGestureRecognizer) {
print("detected tap!")
}
To make this a little clearer these things need to be in place. I used this to make it so if a user entered something in an app of my own's credit textField anything in the debit textField is deleted.
put debit.addTarget and credit.addtarget inside view will appear.
@IBOutlet weak var debit: UITextField! and @IBOutlet weak var credit: UITextField! are textfields on the storyboard and connected to the viewController.
class SecondViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
@IBOutlet weak var credit: UITextField!
@IBOutlet weak var debit: UITextField!
func myDebitDetector(textfield: UITextField ){
print("using debit")
credit.text = ""
}
func myCreditDetector(textfield: UITextField) {
print("using cedit")
debit.text = ""
}
override func viewWillAppear(animated: Bool) {
debit.addTarget(self, action: "myDebitDetector:", forControlEvents: UIControlEvents.TouchDown)
credit.addTarget(self, action: "myCreditDetector:", forControlEvents: UIControlEvents.TouchDown)
....
}
}
Set the UITextField delegate to your view controller
Obj-C
textField.delegate = self;
Swift
textField.delegate = self
Implement the delegate method
Obj-c
-(void)textField:(UITextField*)textField didBeginEditing {
// User touched textField
}
Swift
func textFieldDidBeginEditing(textField: UITextField!) { //delegate method
}
Swift 3.0 Version:
textFieldClientName.addTarget(self, action: Selector(("myTargetFunction:")), for: UIControlEvents.touchDown)
Swift 4.2.
Try .editingDidEnd instead of .touchDown and delegate.
myTextField.addTarget(self, action: #selector(myTargetFunction), for: .editingDidEnd)
@objc func myTargetFunction(textField: UITextField) {
print("textfield pressed")
}
On xamarin.iOS i easy to use:
YourTextField.WeakDelegate = this;
[...]
[Export("textFieldDidBeginEditing:")]
public void TextViewChanged(UITextField textField)
{
if (YourTextField.Equals(textField))
IsYourTextFileFocused = true;
}
** Swift 4.0 + **
Use custom action like this
YourTextField.addTarget(self, action: #selector(myTargetFunction(_:)), for: .allEditingEvents)
@IBAction private func myTargetFunction(_ sender: Any) {
if let textField = sender as? UITextField {
// get textField here
}
}