Two UIGestureRecognizer on one view? - swift

I am using spriteKit. I don't kwon whether this is important. I've initialized two UIGestureRecognizer to my view in didMove(toView):
let longPress = UILongPressGestureRecognizer()
longPress.minimumPressDuration = CFTimeInterval(0.0)
longPress.addTarget(self, action: #selector(self.longPressGesture(longpressGest:)))
self.view?.addGestureRecognizer(longPress)
let swipeUp = UISwipeGestureRecognizer()
swipeUp.direction = UISwipeGestureRecognizerDirection.up
swipeUp.addTarget(self, action: #selector(self.swipeUpGesture(swipe:)))
self.view?.addGestureRecognizer(swipeUp)
My Problem is that only the first gestureRecognizer is called (longpressGest). When I delete the first GestureRecognizer, the swipeGestureRecognizer does work. How can I solve this?

You need to make your Game Scene view the delegate of your gesture recognizer. You will also need implement its method shouldRecognizeSimultaneouslyWith as mentioned by xmasRights:
So in your Game scene declaration just add UIGestureRecognizerDelegate:
class GameScene: SKScene, SKPhysicsContactDelegate, UIGestureRecognizerDelegate {
And in your didMove(to view: SKView) method make set its delegate:
let longPress = UILongPressGestureRecognizer()
longPress.delegate = self
longPress.minimumPressDuration = 0
longPress.addTarget(self, action: #selector(longPressGesture))
view.addGestureRecognizer(longPress)
let swipeUp = UISwipeGestureRecognizer()
swipeUp.delegate = self
swipeUp.direction = .up
swipeUp.addTarget(self, action: #selector(swipeUpGesture))
view.addGestureRecognizer(swipeUp)
Also In Swift 4 you will need to add #objc to your methods
#objc func longPressGesture(_ longPress: UILongPressGestureRecognizer) {
print("longPressGesture")
}
#objc func swipeUpGesture(_ swipeUp: UISwipeGestureRecognizer) {
print("swipeUpGesture")
}
Don't forget also to add the method shouldRecognizeSimultaneouslyWith as already mentioned by xmasRights:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
print("shouldRecognizeSimultaneouslyWith")
return true
}

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool
{
return true
}
https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/coordinating_multiple_gesture_recognizers/allowing_the_simultaneous_recognition_of_multiple_gestures

You could also use the same gesture recognizer and differ between the two gesture inside of this function

Related

Screen edge gesture is not recognized in PDFView (UIViewer) [Swift, iOS 15, PDFKit]

I am displaying a PDF file and would like to add a screen edge gesture to move pages around.
The following code works fine when entire the content of a PDF is displayed on the screen. However, when the PDF was zoomed, the screen edge gesture cannot even activate.
override func viewDidLoad(){
super.viewDidLoad()
//set up gesture to swipe from the edge
let leftScreenEdgeRecognizer = UIScreenEdgePanGestureRecognizer (
target: self, action: #selector(TextDocumentViewController.leftEdgePanGestureHandler(_ : )))
leftScreenEdgeRecognizer.edges = UIRectEdge.left
let rightScreenEdgeRecognizer = UIScreenEdgePanGestureRecognizer (
target: self, action: #selector(TextDocumentViewController.rightEdgePanGestureHandler(_ : )))
rightScreenEdgeRecognizer.edges = UIRectEdge.right
//register the gesture
pdfView.addGestureRecognizer(leftScreenEdgeRecognizer)
pdfView.addGestureRecognizer(rightScreenEdgeRecognizer)
}
//gesture functions here
#objc func leftEdgePanGestureHandler(_ sender: UIScreenEdgePanGestureRecognizer){
if(sender.state == UIGestureRecognizer.State.ended){
print ("Left Edge")
pdfView.goToPreviousPage(sender)
}
}
#objc func rightEdgePanGestureHandler(_ sender: UIScreenEdgePanGestureRecognizer){
if(sender.state == UIGestureRecognizer.State.ended){
print ("right Edge")
pdfView.goToNextPage(sender)
}
}
I tired to add a code like,
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
However, this is not working at all.
I was able to solve this problem thanks to the answer provided for my old question. I have totally forgotten about the post. After learning more about multiple gesture detections through try and error, I realized that I can do as follows to solve this posted question:
Enables the multiple gesture activation:
class ViewController: UIViewController, UIGestureRecognizerDelegate, UIDocumentPickerDelegate, PDFViewDelegate {
// ... other things
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer:
UIGestureRecognizer) -> Bool {
return true
}
}
Make sure to appropriately set delegate.
override func viewDidLoad(){
super.viewDidLoad()
//set gesture
leftScreenEdgeRecognizer.delegate = self
rightScreenEdgeRecognizer.delegate = self
}

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 {

Can't get shouldRecognizeSimultaneouslyWithGestureRecognizer working

I'm working with Swift 3, Xcode and SpriteKit.
I have two gestures: UIPanGestureRecognizer and UIPinchGestureRecognizer
let pinchGesture = UIPinchGestureRecognizer()
let panGesture = UIPanGestureRecognizer()
override func didMove(to view: SKView)
{
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(GameScene.pinchFunction))
view.addGestureRecognizer(pinchGesture)
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(GameScene.panFunction))
view.addGestureRecognizer(panGesture)
}
I want to be able to pinch the screen, and while pinching to move my two fingers, so I want the two gestures to work simultaneously.
But I can't manage to do it. Here's what I tried :
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
What is the correct way to do it ?

Simultaneous gesture recognition for specific gestures

I'm trying to enable simultaneous gesture recognition but only for the UIPinchGestureRecognizer and UIRotationGestureRecognizer gestures. I don't want it to work for any other gestures. If I set the following property to true it allows all gestures to be recognized simultaneously, how can I limit it to just rotating and scaling?
func gestureRecognizer(UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
Make sure your class implements UIGestureRecognizerDelegate
class YourViewController: UIViewController, UIGestureRecognizerDelegate ...
Set the gesture's delegate to self
yourGesture.delegate = self
Add delegate function to your class
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if (gestureRecognizer is UIPanGestureRecognizer || gestureRecognizer is UIRotationGestureRecognizer) {
return true
} else {
return false
}
}
any 2 cents for swift 5.1
// suppose You need to prefer pinch to pan:
//UIGestureRecognizerDelegate
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith shouldRecognizeSimultaneouslyWithGestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer is UIPinchGestureRecognizer {
return true
}
return false
}

ios8 gesture recognizer does not work on WKWebView with swift

i"m trying to implement a long press gesture recognizer on a WKWebView as follows:
var webView: WKWebView?
let longPressRecognizer = UILongPressGestureRecognizer()
override func loadView() {
super.loadView()
var webViewConfig: WKWebViewConfiguration = WKWebViewConfiguration()
webViewConfig.allowsInlineMediaPlayback = true
webViewConfig.mediaPlaybackRequiresUserAction = false
self.webView = WKWebView(frame: self.view.frame, configuration: webViewConfig)
self.view = self.webView!
//hook the long press event
longPressRecognizer.addTarget(self, action: "onLongPress:")
self.webView!.scrollView.addGestureRecognizer(longPressRecognizer)
}
func onLongPress(gestureRecognizer:UIGestureRecognizer){
NSLog("long press detected")
}
i don't get an error but i cant seem to make it trigger the onLongPress function.
You didn't set the delegate of the gesture recognizer.
//hook the long press event
longPressRecognizer.delegate = self
longPressRecognizer.addTarget(self, action: "onLongPress:")
self.webView!.scrollView.addGestureRecognizer(longPressRecognizer)
In case that it still doesn't work, this may probably due to WKWebView already has its own gesture recognizers. Then add the following method to your class:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
And in your event method check for the gesture began:
func onLongPress(gestureRecognizer:UIGestureRecognizer){
if gestureRecognizer.state == UIGestureRecognizerState.Began {
NSLog("long press detected")
}
}