I'm trying to configure an app that simultaneously allows taps and long presses. For example, if you already have one finger pressing on the screen, you can still tap it with another. The code from this single-view app illustrates the problem. The gestureRecognizer function apparently never gets called by the delegator, but I don't understand why or know how to fix the problem.
Any insights would be helpful. Thanks!
// ViewController.swift
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {
@IBOutlet var tapGestureRecognizer: UITapGestureRecognizer!
@IBOutlet var longPressGestureRecognizer: UILongPressGestureRecognizer!
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
print("This gestureRecognizer function should have gotten called!")
return true
}
override func viewDidLoad() {
super.viewDidLoad()
let myTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(reportTap(_:)))
let myLongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(reportLongPress(_:)))
myTapGestureRecognizer.delegate = self
myLongPressGestureRecognizer.delegate = self
}
@IBAction func reportTap(_ sender: UITapGestureRecognizer) {
if tapGestureRecognizer.state == .ended { print("Ended tap.") }
}
@IBAction func reportLongPress(_ sender: UILongPressGestureRecognizer) {
if longPressGestureRecognizer.state == .began { print("Began press...") }
else if longPressGestureRecognizer.state == .ended { print("...ended press.") }
}
}
Thanks, Claude31, for the advice—and for pointing out that my gesture recognizer variables were defined to exist only within viewDidLoad()!
I got the effect I wanted by creating the gesture recognizers programmatically, after first trying and failing to fix my code using the IB-generated gesture recognizers and outlets. Adding the gesture recognizers to the view was the main thing missing from your code, but that was easy to spot. For some reason, though, even the code with the IB-generated recognizers and outlets only allowed simultaneous gestures when I explicitly added the gesture recognizers to the view. Clearly, there's something I don't yet understand about how things get set up behind the scenes. In any case, the link to Ray Wenderlich's site may be helpful, since he show's how to make simultaneous gestures work through IB or code.
In any case, your help got me to a solution (below). Thanks!
// ViewController.swift
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {
var tapGestureRecognizer: UITapGestureRecognizer?
var longPressGestureRecognizer: UILongPressGestureRecognizer?
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func prepareForGestures() {
tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(reportTap(_:)))
longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(reportLongPress(_:)))
tapGestureRecognizer?.delegate = self
longPressGestureRecognizer?.delegate = self
if let tapGestureRecognizer = tapGestureRecognizer {
view.addGestureRecognizer(tapGestureRecognizer)
}
if let longPressGestureRecognizer = longPressGestureRecognizer {
view.addGestureRecognizer(longPressGestureRecognizer)
}
}
override func viewDidLoad() {
super.viewDidLoad()
prepareForGestures()
}
@IBAction func reportTap(_ sender: UITapGestureRecognizer) {
if tapGestureRecognizer?.state == .ended { print("Ended tap.") }
}
@IBAction func reportLongPress(_ sender: UILongPressGestureRecognizer) {
if longPressGestureRecognizer?.state == .began { print("Began press...") }
else if longPressGestureRecognizer?.state == .ended { print("...ended press.") }
}
}