UITapGestureRecognizer to hide keyboard taps on UITableViewCell - swift

I have the below script, and when the keyboard is up, if I click around it in this UIController, it will hide the keyboard, but it will also click on the cell. I do not want that to happen.
I know that cancelsTouchesInView will control that feature... and if I set it to true, it wont click on the cell, BUT I can't click on the cell after the keyboard is hidden.
Is there a good solution for this?
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard2))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard2() {
view.endEditing(true)
}
}

Your best bet may be to disable user interaction on your tableView when the keyboard is shown, and then re-enable it when you end editing.
However, you might give this a try and see if it does what you need.
Change your signature for the dismissKeyboard2 func to get a reference to the tap gesture recognizer and remove it when you end editing:
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard2(_:)))
tapGesture.cancelsTouchesInView = true
view.addGestureRecognizer(tapGesture)
}
#objc func dismissKeyboard2(_ g: UITapGestureRecognizer) {
view.endEditing(true)
view.removeGestureRecognizer(g)
}
}

Related

How do I dismiss the number pad keyboard?

In Xcode I selected the Number Pad under Keyboard Type for a label. It works fine, but I cannot dismiss the keyboard and it's blocking important content. How do I get the number pad to close?
you can use to dismiss the keyboard
view.endEditing(true)
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(UIInputViewController.dismissKb))
view.addGestureRecognizer(tap)
}
#objc func dismissKb() {
view.endEditing(true)
}

how to add pan gesture on long pressing a button [duplicate]

I want to trigger two action on button click and button long click. I have add a UIbutton in my interface builder. How can i trigger two action using IBAction can somebody tell me how to archive this ?
this is the code i have used for a button click
#IBAction func buttonPressed (sender: UIButton) {
....
}
can i use this method or do i have to use another method for long click ?
If you want to perform any action with single tap you and long press the you can add gestures into button this way:
#IBOutlet weak var btn: UIButton!
override func viewDidLoad() {
let tapGesture = UITapGestureRecognizer(target: self, #selector (tap)) //Tap function will call when user tap on button
let longGesture = UILongPressGestureRecognizer(target: self, #selector(long)) //Long function will call when user long press on button.
tapGesture.numberOfTapsRequired = 1
btn.addGestureRecognizer(tapGesture)
btn.addGestureRecognizer(longGesture)
}
#objc func tap() {
print("Tap happend")
}
#objc func long() {
print("Long press")
}
This way you can add multiple method for single button and you just need Outlet for that button for that..
#IBOutlet weak var countButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
addLongPressGesture()
}
#IBAction func countAction(_ sender: UIButton) {
print("Single Tap")
}
#objc func longPress(gesture: UILongPressGestureRecognizer) {
if gesture.state == UIGestureRecognizerState.began {
print("Long Press")
}
}
func addLongPressGesture(){
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(gesture:)))
longPress.minimumPressDuration = 1.5
self.countButton.addGestureRecognizer(longPress)
}
Why not create a custom UIButton class, create a protocol and let the button send back the info to delegte. Something like this:
//create your button using a factory (it'll be easier of course)
//For example you could have a variable in the custom class to have a unique identifier, or just use the tag property)
func createButtonWithInfo(buttonInfo: [String: Any]) -> CustomUIButton {
let button = UIButton(type: .custom)
button.tapDelegate = self
/*
Add gesture recognizers to the button as well as any other info in the buttonInfo
*/
return button
}
func buttonDelegateReceivedTapGestureRecognizerFrom(button: CustomUIButton){
//Whatever you want to do
}

How to disable tap gesture recognizer UIButton for dismisskeyboard?

I have this code:
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap = UITapGestureRecognizer(target: self, action: #selector(self.dissmissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
// Don't handle button taps
return !(touch.view is UIButton)
}
This is a global function!
When I press the login button the keyboard disappears and then I must to press it again to login. Is there a way to avoid this?
I want that when I press login button keyboard not disappear but when I press outside button keybord disappear
What you are missing is the delegate.
tap.delegate = self
Since you haven't add the delegate, your
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
method will not execute.
Have a breakpoint there and see that it is execute or not. I don't think so. By adding the delegate that I mentioned earlier will do the trick.
The code will be look like below.
let tap = UITapGestureRecognizer(target: self, action: #selector(self.dissmissKeyboard))
tap.delegate = self
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
In the class you should implement the delegate class like below.
class ViewController: UIViewController, UIGestureRecognizerDelegate {

swift UITapGestureRecognizer not working on view

I had to create a new thread bcoz it's driving me crazy and all the other answers online are exactly the same. I have done this countless of times but I cannot see what I am missing for the life of me. I am using a "test" view controller just to get the tap gesture working but it isn't working at all... I am fairly certain that I am setting this up correctly, as this is how I've always implemented it in the past: (yes, I have checked the box for isUserInteractionEnabled). I am even implementing this on a different viewcontroller this exact way and it is working...
class TestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(tap)
}
let tap = UITapGestureRecognizer(target: self, action: #selector(wasTapped))
#objc func wasTapped() {
print("tapped")
}
}
I have also tried adding the parameters to wasTapped:
#objc func wasTapped(gestureRecognizer: UITapGestureRecognizer) {
print("tapped")
}
You are saying:
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(tap)
}
let tap = UITapGestureRecognizer(target: self, action: #selector(wasTapped))
The problem is the last line:
let tap = UITapGestureRecognizer(target: self, action: #selector(wasTapped))
You cannot just say let tap like that in the middle of nowhere. You are implicitly making an instance property. But you cannot initialize an instance property with a target of self, because self does not exist at the time an instance property is initialized. (I regard the fact that that code even compiles as a bug, and have reported it as such.)
Move that line to the start of viewDidLoad, like this:
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(wasTapped))
view.addGestureRecognizer(tap)
}
Try something like this
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(wasTapped(sender:)))
tap.numberOfTapsRequired = 1 // Default value
view.isUserInteractionEnabled = true
view.addGestureRecognizer(tap)
}
#objc func wasTapped(sender: UITapGestureRecognizer) {
print("tapped")
}
You have to enable interaction if you want to use gesture recognizers for standard UIView's
Add view.isUserInteractionEnabled = true in your viewDidLoad.
var tapGesture = UITapGestureRecognizer()
take a view and set IBOutlet like:
#IBOutlet weak var viewTap: UIView!
Write pretty code on viewDidLoad() like:
tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.myviewTapped(_:)))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
viewTap.addGestureRecognizer(tapGesture)
viewTap.isUserInteractionEnabled = true
this method is calling when tap gesture recognized:
#objc func myviewTapped(_ sender: UITapGestureRecognizer) {
if self.viewTap.backgroundColor == UIColor.yellow {
self.viewTap.backgroundColor = UIColor.green
}else{
self.viewTap.backgroundColor = UIColor.yellow
}
}

UITapGestureRecognizer for UIPIckerView

UITapGestureRecognizer with UIPickerView not working. Why?
class someVC: UIViewController, UITapGestureRecognizerDelegate
override func viewDidLoad() {
let tap = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
self.pickerView.addGestureRecognizer(tap)
tap.delegate = self
}
func dismissKeyboard() {
textField.resignFirstResponder()
}
I solved problem by adding override getureRecognizer
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
Looks ok, could it be that there is another gesture recognizer swallowing the tap? You need to make sure your object is on the top of the view stack to ensure it gets fired. Also you set the delegate, does the delegate methods get called? or do they not fire either? If they don't then it means your tap gesture is not being touched(another gesture is taking the touch), if it does get fired, it means there is something wrong with the action(but i doubt that is the case).