I added a tap and double tap gesture recognizer to a text field in swift, so that the single tap performs a function but the double tap actually makes the Textfield become first responder. it stops working though after the textfield becomes first responder for the first time. That is, the textfield operates as normally by becoming first responder on a single tap rather than double tap. Any ideas on how to keep my gesture recognizers working?
Swift Gesture recognizers added to textfield inoperable after becomes first responder?
4.3k views Asked by Justin Leonard At
3
There are 3 answers
1
On
Logically it would be easier if you follow these step instead:
- set "editable" false to the texField
- on doubleTap action implementation make the textfield editable to true and call becomeFirstResponder so that user can type.
- implement textfield delegate method -textFieldDidEndEditing and again make that textField non-editable by setting "editable" property to false.
0
On
I have a similar problem, wanting a single tap to alternate between displaying and hiding a UIPicker.
The problem is that UITextField adds its own gesture recognizers. So, subclass UITextField and add your own, but disallow the default gesture recognizers from being added.
class MyTextField: UITextField
{
fileprivate var tap1Gesture: UITapGestureRecognizer?
fileprivate var tap2Gesture: UITapGestureRecognizer?
required init?( coder aDecoder: NSCoder )
{
super.init( coder: aDecoder )
gestureRecognizers = nil
tap1Gesture = UITapGestureRecognizer( target: self, action: #selector( tapped1( _: ) ) )
addGestureRecognizer( tap1Gesture! )
tap2Gesture = UITapGestureRecognizer( target: self, action: #selector( tapped2( _: ) ) )
tap2Gesture.numberOfTapsRequired = 2
addGestureRecognizer( tap2Gesture! )
}
override func addGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer)
{
if gestureRecognizer == tap1Gesture || gestureRecognizer == tap2Gesture
{
super.addGestureRecognizer( gestureRecognizer )
}
}
internal func tapped1( _ sender: UITapGestureRecognizer )
{
// Do your "performs a function"
}
internal func tapped2( _ sender: UITapGestureRecognizer )
{
if self.isFirstResponder
{
_ = self.resignFirstResponder()
}
else
{
self.becomeFirstResponder()
}
}
}
If you want to hide selection of text, you can also add the following to your derived class (with help http://www.b2cloud.com.au/tutorial/disabling-the-caret-and-text-entry-in-uitextfields/):
extension MyTextField
{
override var selectedTextRange: UITextRange?
{
get { return nil }
set { return }
}
override func canPerformAction( _ action: Selector, withSender sender: Any? ) -> Bool
{
return false
}
override func caretRect( for position: UITextPosition ) -> CGRect
{
return .zero
}
}
Another approach:
Just create an 'invisible' view on top of the textfield and add the gesture recognizers to it