My view hierarchy is following:
View
- View For User's Img + Emoji (A)
- View With UI elements. (B)
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)
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 theviewForImgAndEmoji
. This way, any on screen touches reachviewForImgAndEmoji
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 :)You might need to implement the following delegate method: