UIGesturerecognizer is not working on UIView - ios

When I am tapping on UIView but Gesture is not working.
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
viewForSHadow.isUserInteractionEnabled = true
viewForSHadow.addGestureRecognizer(tap)
// Do any additional setup after loading the view.
}
func handleTap(_sender: UITapGestureRecognizer) {
print("---------View Tapped--------")
viewForSHadow.isHidden = true
viewForAlert.isHidden = true
}
I just want to perform this action on UIView tap.

You may check in the debug view hierarchy if anything with alpha = 0 is overlapping your viewForSHadow.

You have to implement as follows:
class ViewController: UIViewController, UIGestureRecognizerDelegate {
...
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_sender:)))
viewForSHadow.isUserInteractionEnabled = true
viewForSHadow.addGestureRecognizer(tap)
}
#objc func handleTap(_sender: UITapGestureRecognizer) {
print("---------View Tapped--------")
viewForSHadow.isHidden = true
viewForAlert.isHidden = true
}
...
}

Your code is more than enough to have working UIGestureRecognizer, you should check some other stuff like, is there something else that can consume the user interaction. And also to check if you use
isUserInteractionEnabled = false
to some parent view of viewForSHadow.

You have to use UIGestureRecognizerDelegate
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleDismiss))
tapRecognizer.delegate = self
blackView.addGestureRecognizer(tapRecognizer)
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return true
}
#objc func handleDismiss() {
print("handleDismiss")
}
Reference
Don't forget to set the UIGestureRecognizerDelegate in your class

You need to mention numberOfTapsRequired property of the UITapGestureRecognizer.
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_sender:)))
tap.numberOfTapsRequired = 1
viewForSHadow.isUserInteractionEnabled = true
viewForSHadow.addGestureRecognizer(tap)
}
#objc func handleTapGesture(_sender: UITapGestureRecognizer) {
print("---------View Tapped--------")
// Why are you hiding this view **viewForSHadow**
viewForSHadow.isHidden = true
viewForAlert.isHidden = true
}
Also, make sure you are not doing viewForSHadow.isUserInteractionEnabled = false anywhere in the code.

First of all you code doesn't compile. The handleTap(_:) signature must be like:
#objc func handleTap(_ sender: UITapGestureRecognizer) {
print("---------View Tapped--------")
}
Secondly, you need to first try with the minimal code in a separate project. And by minimal code I mean what you've added in the question.
class ViewController: UIViewController {
#IBOutlet weak var viewForSHadow: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
viewForSHadow.addGestureRecognizer(tap)
}
#objc func handleTap(_ sender: UITapGestureRecognizer) {
print("---------View Tapped--------")
}
}
Try with just the above code and see if you can get it working. The above code is working well at my end without any delegate or numberOfTaps.

Related

Container view's collectionVC blocked with Parent's tapGesture recognizer

I have an extension of UIViewController as follows to dismiss the keyboard if the user taps on the screen. Within this view I have a scroll containing textfields and two container views. The container views contain a collectionView. I want my overall viewController to dismiss when tapped around but I still want my collectionView's didSelectitemAtIndexPath to trigger. How can I achieve this?
public extension UIViewController {
public func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
public func dismissKeyboard() {
view.endEditing(true)
}
}
and
class RegisterVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
logViewLoad()
self.hideKeyboardWhenTappedAround()
let controller = self.storyboard?.instantiateViewController(withIdentifier: "CollectionViewSearchVC") as! CollectionViewSearchVC
controller.type = "SC"
addChildViewController(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
controller.delegate = self
containerView.addSubview(controller.view)
NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
controller.view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
controller.view.topAnchor.constraint(equalTo: containerView.topAnchor),
controller.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
])
controller.didMove(toParentViewController: self)
subContractorVC = controller
let employeeController = self.storyboard?.instantiateViewController(withIdentifier: "CollectionViewSearchVC") as! CollectionViewSearchVC
employeeController.type = "V"
employeeController.delegate = self
addChildViewController(employeeController)
employeeController.view.translatesAutoresizingMaskIntoConstraints = false
employeeContainerView.addSubview(employeeController.view)
NSLayoutConstraint.activate([
employeeController.view.leadingAnchor.constraint(equalTo: employeeContainerView.leadingAnchor),
employeeController.view.trailingAnchor.constraint(equalTo: employeeContainerView.trailingAnchor),
employeeController.view.topAnchor.constraint(equalTo: employeeContainerView.topAnchor),
employeeController.view.bottomAnchor.constraint(equalTo: employeeContainerView.bottomAnchor)
])
employeeController.didMove(toParentViewController: self)
}
Implement the delegate methods for the GestureRecogniser in your ViewController and check for the class which is being touched, if that is of kind UICollectionView, then ignore that touch and let it do the default behaviour, i.e didSelect otherwise allow tap.
class ParentViewController: UIViewController {
var tap: UITapGestureRecognizer?
override func viewDidLoad() {
super.viewDidLoad()
tap = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard))
view.addGestureRecognizer(tap!)
}
public func hideKeyboardWhenTappedAround() {
dismissKeyboard()
}
#objc public func dismissKeyboard() {
view.endEditing(true)
}
}
class RegisterVC: ParentViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
tap?.delegate = self
// YOUR EXISTING CODE HERE
}
// NEW CODE ADDED HERE
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
print("shouldReceive")
print(gestureRecognizer.view as Any) // CHECK FOR WHICH CLASS YOU ARE GETTING HERE WHEN YOU CLICK ON COLLECTIONVIEW
if (gestureRecognizer.view?.isKind(of: UICollectionView.self))! {
return false
}
return true
}
}
Try it and share the results.
You need to create a view behind the child VC's views and add the gesture to it

How do I give a UIButton in Swift 4 multiple taps to print a different string back to the outputLabel? Goal is to create T9 Text

I'm having problems trying to get a UI button to have multiple taps I know it's not ideal but if someone could show me what I'm doing wrong or point me in the right direction that would be great. Below is my current code where I'm trying to create a function called two pressed that responds based off how many times its tapped.
var resultOfLabel = ""
#IBOutlet weak var outputLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture1 = UITapGestureRecognizer(target: self, action: #selector(singleTap(gesture:)))
UIButton.addGestureRecognizer(tapGesture1)
let tapGesture2 = UITapGestureRecognizer(target: self, action: #selector(doubleTap(gesture:)))
tapGesture2.numberOfTapsRequired = 2
UIButton.addGestureRecognizer(tapGesture2)
let tapGesture3 = UITapGestureRecognizer(target: self, action: #selector(tripleTap(gesture:)))
tapGesture3.numberOfTapsRequired = 3
UIButton.addGestureRecognizer(tapGesture3)
let tapGesture4 = UITapGestureRecognizer(target: self, action: #selector(quadrupleTap(gesture:)))
tapGesture4.numberOfTapsRequired = 4
UIButton.addGestureRecognizer(tapGesture4)
// Do any additional setup after loading the view.
}
#IBAction func twoPressed(sender: UIButton) {
#objc func singleTap() {
print(“2”)
}
#objc func doubleTap() {
print(“a”)
}
#objc func tripleTap() {
print(“b”)
}
#objc func quadrupleTap() {
print(“c”)
}
resultOfLabel += "\(sender)"
outputLabel.text = resultOfLabel
}
There is no problem in that except get these 4 functions out of the IBAction method
let tapGesture1 = UITapGestureRecognizer(target: self, action: #selector(self.singleTap(_:)))
UIButton.addGestureRecognizer(tapGesture1)
//
#objc func singleTap(_ sender: UITapGestureRecognizer? = nil) {
print(“2”)
self.twoPressed(sender.View as! UIButton)
}
#objc func doubleTap() {
print(“a”)
}
#objc func tripleTap() {
print(“b”)
}
#objc func quadrupleTap() {
print(“c”)
}
#IBAction func twoPressed(sender: UIButton) {
resultOfLabel += "\(sender)"
outputLabel.text = resultOfLabel
}

UITapGestureRecognizer breaks UITableView didSelectRowAtIndexPath in SearchField Class in Swift?

I am using this library for SearchText Field
https://github.com/apasccon/SearchTextField
Here is my Code :
override func viewDidLoad() {
super.viewDidLoad()
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: Selector("dismissKeyboard")))
}
func dismissKeyboard()
{
ClientList.resignFirstResponder()
self.view.endEditing(true)
}
Dismiss of keyboard is working but the didSelectRowAtIndexPath is not getting called so i am not able to select anything
Image for Reference :
Partial Solution I Done:
func hideKeyboard(gestureRecognizer: UIGestureRecognizer) {
let point = gestureRecognizer.locationInView(ClientList.tableView)
let indexPath = ClientList.tableView!.indexPathForRowAtPoint(point)
if indexPath != nil {
return
}
if ClientList.becomeFirstResponder() {
ClientList.resignFirstResponder()
}
}
But now issue is i have other list too , how can i implement for other list ?
You can solve this issue like this
ViewDidLoad
self.tap = UITapGestureRecognizer(target: self, action: "viewTapped:")
self.tap.delegate = self
self.view.addGestureRecognizer(self.tap)
Function
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if touch.view != nil && touch.view!.isDescendantOfView(self.tableView) {
return false
}
return true
}
Who's the target of the gesture? I think it should be the list since it is what you tap and it is above the view
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
view.addGestureRecognizer(tap)
Add this to viewDidLoad
And add this function
func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
}

UITapGesture on UIImageview not Working

I'm trying too make UIImage as button using UITapGesture.
let contactSegueIdentifier = "showContactSegue"
override func viewDidLoad() {
initTapGestureRec()
}
func initTapGestureRec() {
let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("recognizeTapGesture:"))
brandMenuContactImage.addGestureRecognizer(tapGesture)
}
func recognizeTapGesture(sender: UIGestureRecognizer) {
self.performSegueWithIdentifier(contactSegueIdentifier, sender: self)
}
When I run and tap the image, nothing happened. Can anyone help me please.
add userInteractionEnabled true on your image and try
brandMenuContactImage.userInteractionEnabled = true
objective-C
brandMenuContactImage.userInteractionEnabled = YES;
Update
override func viewDidLoad() {
brandMenuContactImage.userInteractionEnabled = true
initTapGestureRec()
}

TabBar hides in viewDidLoad but doesnt in gesture function

I tried calling tabBarController!.tabBar.hidden = true in viewDidLoad() and it hides the TabBar. However, I tried to set tap gesture and hide the bar on Tap. The parent viewController that has ScrollView inside it with subview (that is connected with IBOutlet as myView)
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
myView.addGestureRecognizer(tap)
}
func handleTap(sender: UITapGestureRecognizer? = nil) {
print("A") // logs successfully
if TabBarHidden == false {
print("B") // logs successfully
//I tried:
tabBarController?.tabBar.hidden = true
// I also tried
tabBarController?.tabBar.alpha = 0
tabBarController?.tabBar.frame.origin.x += 50
hidesBottomBarWhenPushed = true
} else {
...
TabBarHidden = false
}
}
hidden does work when I call it in viewDidLoad as I said, but not if I call in tap gesture function. What may be the problem? What am I missing?
this code totally works for me:
class ViewController: UIViewController {
var tabBarHidden: Bool = false {
didSet {
tabBarController?.tabBar.hidden = tabBarHidden
}
}
override func viewDidLoad() {
super.viewDidLoad()
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapGestureRecognized(_:)))
view.addGestureRecognizer(tapGestureRecognizer)
}
func tapGestureRecognized(sender: UITapGestureRecognizer) {
tabBarHidden = !tabBarHidden
}
}

Resources