Evgeny
Evgeny

Reputation: 384

UIPanGestureRecognizer isn't firing up. Swift 3

My view hierarchy is following:

In viewDidLoad, I create UIImageViews for emojis, add them to the A and add gesture recognizers (pan,pinch,rotate):

 let emojiView = UIImageView(image: emoji)
            emojiView.tag = n
            emojiView.frame = CGRect(x: 153, y: 299, width: 70, height: 70)
            emojiView.isUserInteractionEnabled = true

            let pan = UIPanGestureRecognizer(target: self, action: #selector(self.handlePan(recognizer:)))
            pan.delegate = self
            emojiView.addGestureRecognizer(pan)

            let pinch = UIPinchGestureRecognizer(target: self, action: #selector(self.handlePinch(recognizer:)))
            pinch.delegate = self
            emojiView.addGestureRecognizer(pinch)

            let rotate = UIRotationGestureRecognizer(target: self, action: #selector(self.handleRotate(recognizer:)))
            rotate.delegate = self
            emojiView.addGestureRecognizer(rotate)

Later, I declare IBActions:

@IBAction func handlePan(recognizer: UIPanGestureRecognizer) {
    let translation = recognizer.translation(in: self.viewForImgAndEmoji)
    if let view = recognizer.view {
        view.center = CGPoint(x:view.center.x + translation.x,
                              y:view.center.y + translation.y)
    }
    recognizer.setTranslation(CGPoint.zero, in: self.viewForImgAndEmoji)
}

@IBAction func handlePinch(recognizer: UIPinchGestureRecognizer) {

    let pinchPoint = recognizer.location(in: viewForImgAndEmoji)
    let ourEmojiView = viewForImgAndEmoji.hitTest(pinchPoint, with: nil)

    ourEmojiView!.transform = ourEmojiView!.transform.scaledBy(x: recognizer.scale, y: recognizer.scale)
    recognizer.scale = 1

}

@IBAction func handleRotate(recognizer: UIRotationGestureRecognizer){

    let rotatePoint = recognizer.location(in: viewForImgAndEmoji)
    let ourEmojiView = viewForImgAndEmoji.hitTest(rotatePoint, with: nil)

    ourEmojiView!.transform = ourEmojiView!.transform.rotated(by: recognizer.rotation)
    recognizer.rotation = 0
}

Problem: the pan func isn't firing up. Rotate and pinch works. But panning isn't. (Can't disable user interaction for overlaying view since it has buttons)

Upvotes: 1

Views: 1339

Answers (2)

Fahim
Fahim

Reputation: 3556

OK, I took a look at the code and I see two possible issues:

1: You have pinch, pan, and rotate gesture recognizers set in the storyboard as well. These might be superfluous. Just mentioning that. This really isn't the issue your pan gesture recognizer isn't working though.

2: The UIView for controls covers your emoji and image view and will take over touches. You don't need a full-screen view for the UI controls since you don't seem to do anything with the view itself. Instead, you can simply put the button at the right position on the main screen over the viewForImgAndEmoji. This way, any on screen touches reach viewForImgAndEmoji except at the spots where you have the buttons.

I modified the storyboard that way and I could get the pan gestures fine at that point. Do let me know if you need me to clarify anything since I am not sure if I was clear enough about the issue :)

Note: One issue that you will run into when you fix the above is that you will find that not all touches register because the gesture recognizer is attached to each sticker and the sticker itself might be too small to detect something like a pinch gesture. You might be better off adding viewForImgAndEmoji as the gesture handler and activating each sticker/emoji as the recipient of the the gesture based on selecting the emoji by a tap before you try to pinch, rotate, or pan. Just a suggestion :)

Upvotes: 1

Stefan S
Stefan S

Reputation: 741

You might need to implement the following delegate method:

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

Upvotes: 1

Related Questions