Can't get shouldRecognizeSimultaneouslyWithGestureRecognizer working - swift

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 ?

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 {

Two UIGestureRecognizer on one view?

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

How to access Siri Remote play/pause button and override menu button

How can I access the play/pause button with the Siri remote and override the menu button? I am currently using this, but it is not working for me. My program crashes when I use this code but only when I call it four example pressing the pause button
The coders is currently positioned below didMoveToView next to touchesBegan
let tapGesture = UITapGestureRecognizer(target: self, action: "handleTap:")
tapGesture.allowedPressTypes = [NSNumber(integer: UIPressType.Menu.rawValue)]
self.view.addGestureRecognizer(tapGesture)
Your issue is you're calling a function called handleTap: that receives a parameter but you don't have a function called handleTap:. That's what action represents in this line:
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
Change your func tapped() to:
func handleTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Ended {
print("Menu button released")
}
}
I use the following for Swift 4 (as per question: #selector() in Swift?)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
tapGesture.allowedPressTypes = [NSNumber(integer: UIPressType.Menu.rawValue)]
self.view.addGestureRecognizer(tapGesture)
#objc func handleTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Ended {
print("Menu button released")
}
}
I solved my problem by moving the tapRecognizer selector into my previously set up touch handler function so the code looks like this now:
private func handleTouches(touches: Set<UITouch>) {
for touch in touches {
let touchLocation = touch.locationInNode(self)
lastTouch = touchLocation
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
tapRecognizer.allowedPressTypes = [NSNumber(integer: UIPressType.PlayPause.rawValue)];
self.view!.addGestureRecognizer(tapRecognizer)
}
}
func handleTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Ended {
print("Menu button released")
}
}

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")
}
}