Uitapgesturerecognizer Called Immediately

UITapGestureRecognizer called immediately

You should use following syntax:

let gest = UITapGestureRecognizer(target: self, action: #selector(imgPressed))

Note, that Selector can accept initial type Void as well as String. Properly old-style Selector initialization looks like this:

let action: Selector = Selector("imgPressed")

Now you may check, that if you will try combine new style with old style you will get compilation error:

let action = Selector(imgPressed) // Error!

Funny thing is that you probably will try to resolve this error by appending bracers, and you will not have any errors after that! But this is completely useless. Look at following 3 lines of code, they are equivalent

let action = Selector(imgPressed())
let action = Selector(Void())
let action = Selector()

exept one thing - in first line you called imgPressed() function, returned Void, by your hands. Thats it =)

UITapGestureRecognizer called only once

My code was fine answering my own issue.
The problem was the line: addSubview(imageView)

I was adding 4 placeholder (about 300px) to a container smaller than the sum of the widths of all my placeholders.
Although I was seeing all the placeholders correctly displayed, the frame wasn't big enough to contain them and so the double tap not recognised.
Making the container bigger solved the issue.

Swift3 iOS - How to make UITapGestureRecognizer trigger function

From your code you are using swift 3.0 so change your selector syntax like this

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tapBlurButton(_:)))

and Your function like this

func tapBlurButton(_ sender: UITapGestureRecognizer) {
print("Please Help!")
}

Edit:

Not idea that you are using button with tap gesture, instead of that use inbuilt method addTarget for button no need to create tap gesture for it like this

qsBlurButton.addTarget(self, action: #selector(self.tapBlurButton(_:)), forControlEvents: .TouchUpInside)

func tapBlurButton(_ sender: UIButton) {
print("Please Help!")
}

Swift UITapGestureRecognizer not calling

The target should be the coordinator (which is a persistent entity, unlike the transient View), not self.

let focusGesture = UITapGestureRecognizer(target: context.coordinator, action: #selector(context.coordinator.tapFocus(_:)))

Gesture recognizer code being called twice after leaving and coming back to view

Move the tap gesture code into viewDidLoad and not viewDidAppear

let doubleTap = UITapGestureRecognizer(target: self, action: #selector(self.doubleTapAction(sender:)))
doubleTap.numberOfTapsRequired = 2
self.addGestureRecognizer(doubleTap)

viewDidAppear will be called every time you go back to that screen. You don't need to remove the gesture recognisers when you move to a different screen - they will only be called when that view is visible.

Why is touchesCancelled being called after UITapGestureRecognizer?

That's just what a gesture recognizer is / does. When a gesture recognizer recognizes its gesture, the touches for this gesture recognizer are sent to their hit-test views as a touchesCancelled(_:with:) message, and then no longer arrive at those views. The gesture recognizer takes over so it signs the view off from its touch sequence in good order.

If you're going to have both a gesture recognizer and manual touch events, you have to do more work to mediate between them. If you really don't want the standard behavior, you can set the gesture recognizer's cancelsTouchesInView property to false.

How to create UIBarButton to call UITapGestureRecognizer function using Swift?

If you need to call both these tap gesture recognizer functions from a UIBarButtonItem, your best bet is to create a custom view bar button item and add gesture recognizers to that custom view. Something like this would work:

let tapGestureView = UIView() // initialize & size this as you need
tapGestureView.addGestureRecognizer(UITapGestureRecognizer(action: #selector(handleCardTap(_:)), target: self))
tapGestureView.addGestureRecognizer(UITapGestureRecognizer(action: #selector(handleCardPan(_:)), target: self))
let barButton = UIBarButtonItem(customView: tapGestureView)

Here are some additional resources for UITapGestureRecognizers
and UIBarButtonItems. It seems a bit odd to set up 2 different tap gestures for the same view, though, and one of them being a pan action (at least by name) seems odd, but this is how you'd accomplish that!

Triggering UITapGestureRecognizers from overlapping Views

First you should conform to UIGestureRecognizerDelegate in your VC, and then implement the delegate func of shouldRecognizeSimultaneouslyWith. Inside the function, you should detect if the gestureRecognizer, and the otherGestureRecognizer are the wants you want, and if so, you should allow them to work simultaneously,

  • Conform to delegate, and Declare gesture recognizers outside of viewDidLoad (because you need to access them in the delegate method later.)

    var mainGestureRecognizer = UITapGestureRecognizer()
    var subGestureRecognizer = UITapGestureRecognizer()

  • Initialize your recognizers, and set your VC as their delegate:

    mainGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(mainGestureActivated))
    subGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(subViewGestureActivated))
    mainGestureRecognizer.delegate = self
    subGestureRecognizer.delegate = self
  • Implement the delegate function mentioned above to allow simultaneous recognition for subView and mainView:

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    if gestureRecognizer == subGestureRecognizer && otherGestureRecognizer == mainGestureRecognizer {
    return true
    }

    return false
    }

And if you want it to work for 4 different subviews, then you should check with else if statements inside the delegate method.

Resolve UITapGestureRecognizer and UILongPressGestureRecognizer simultaneously and fire UIGestureRecognizer.State.began on finger touch down

I wonder if your implementation of shouldRequireFailureOf is causing an issue?

This works just fine for me (note: I used .minimumPressDuration = 0.25 because it's a little difficult to tap in under 0.1 seconds):

class GestureTestViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
setupTapGestures()
}

private func setupTapGestures() -> Void {

let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
view.addGestureRecognizer(singleTapGesture)

let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture(_:)))
longPressGesture.minimumPressDuration = 0.25
view.addGestureRecognizer(longPressGesture)

}

@objc func handleLongPressGesture(_ gesture: UILongPressGestureRecognizer) -> Void {
if gesture.state == .began {
print("Did Long Press (began)")
}
if gesture.state == .ended {
print("Did Long Press (ended)")
}
}

@objc func handleTapGesture(_ gesture: UITapGestureRecognizer) -> Void {
print("Did Single Tap")
}

}

When I tap, I get "Did Single Tap" in the debug console.

When I tap and hold, I quickly get "Did Long Press (began)", and on finger-lift I get "Did Long Press (ended)"



Related Topics



Leave a reply



Submit