Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Labels Animation Same as Phibrow App

I want to create same animation as in Phibrow App. Please see following video for more details:- https://www.dropbox.com/s/wwc69a9ktaa52je/IMG_0155.MOV?dl=0

enter image description here enter image description here enter image description here

I have tried to get this animation using UIPinchGestureRecognizer, UIRotationGestureRecognizer and UIPanGestureRecognizer. But not able to get this animation yet.

func handlePinchGesture(gesture: UIPinchGestureRecognizer) {
    if gesture.state == UIGestureRecognizerState.began || gesture.state == UIGestureRecognizerState.changed{
        //print("UIPinchGestureRecognizer")

        gesture.view?.transform = (gesture.view?.transform)!.scaledBy(x: gesture.scale, y: gesture.scale)
        gesture.scale = 1.0
    }
}


func handleRotationGesture(gesture: UIRotationGestureRecognizer) {
    if gesture.state == UIGestureRecognizerState.began || gesture.state == UIGestureRecognizerState.changed{
        print("UIRotationGestureRecognizer : ", gesture.rotation)
        gesture.view?.transform = (gesture.view?.transform)!.rotated(by: gesture.rotation)
        gesture.rotation = 0
    }
}

func handlePanGesture(gesture: UIPanGestureRecognizer) {
    if gesture.state == UIGestureRecognizerState.began || gesture.state == UIGestureRecognizerState.changed{
        //print("UIPanGestureRecognizer")
        let translation = gesture.translation(in: view)
        gesture.view?.transform = (gesture.view?.transform)!.translatedBy(x: translation.x, y: translation.y)
        gesture.setTranslation(CGPoint(x: 0, y: 0), in: view)
    }
}

Is there any way to get this animation?

like image 927
Meet Doshi Avatar asked Dec 26 '17 07:12

Meet Doshi


2 Answers

I think this code works for you. I have declared two views firstView and secondView and added separate gesture for both the views like if in case of panGesture for example :

firstPan = UIPanGestureRecognizer(target: self, action: #selector(self.handlePanGesture(gesture:)))
    secondPan = UIPanGestureRecognizer(target: self, action: #selector(self.handlePanGesture(gesture:)))
    firstView.addGestureRecognizer(secondPan!)
    secondView.addGestureRecognizer(firstPan!)

for pinch and rotation i have used same method as above to add gesture. and for your case you need to have pinch and rotation gesture except pan gesture works at a same time for both views so just check which view and apply transform for other view also.

@objc func handlePinchGesture(_ gestureRecognizer: UIPinchGestureRecognizer) {
    guard gestureRecognizer.view != nil else { return }
    if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
        if gestureRecognizer.view == firstView {
            gestureRecognizer.view?.transform = (gestureRecognizer.view?.transform.scaledBy(x: gestureRecognizer.scale, y: gestureRecognizer.scale))!
            secondView.transform = (secondView.transform.scaledBy(x: gestureRecognizer.scale, y: gestureRecognizer.scale))
            gestureRecognizer.scale = 1.0
        }else{
            gestureRecognizer.view?.transform = (gestureRecognizer.view?.transform.scaledBy(x: gestureRecognizer.scale, y: gestureRecognizer.scale))!
            firstView.transform = (firstView.transform.scaledBy(x: gestureRecognizer.scale, y: gestureRecognizer.scale))
            gestureRecognizer.scale = 1.0
        }
    }
}


@objc func handleRotationGesture(gesture: UIRotationGestureRecognizer) {
    if gesture.state == UIGestureRecognizerState.began || gesture.state == UIGestureRecognizerState.changed{
        if gesture.view == firstView {
            gesture.view?.transform = (gesture.view?.transform)!.rotated(by: gesture.rotation)
            secondView.transform = (secondView.transform).rotated(by: gesture.rotation)
            gesture.rotation = 0
        }else{
            gesture.view?.transform = (gesture.view?.transform)!.rotated(by: gesture.rotation)
            firstView.transform = (firstView.transform).rotated(by: gesture.rotation)
            gesture.rotation = 0
        }
    }
}

@objc func handlePanGesture(gesture: UIPanGestureRecognizer) {
    if gesture.state == UIGestureRecognizerState.began || gesture.state == UIGestureRecognizerState.changed{
        let translation = gesture.translation(in: view)
        gesture.view?.transform = (gesture.view?.transform)!.translatedBy(x: translation.x, y: translation.y)
        gesture.setTranslation(CGPoint(x: 0, y: 0), in: view)
    }
}
like image 72
Shezad Avatar answered Nov 01 '22 20:11

Shezad


The problem I see is that translation is retrieved like gesture.translation(in: view), e.g. in the coordinate system of some view. Is the view in your example a gesture.view.superview? You're interested in how much the gesture.view is moved in its superview coordinate system, so this condition must be true: view == gesture.view.superview.

The second problem is translating of the transform - it will not be correct when rotation and/or scale are non-identity. To properly move the gesture.view, you should change its center position, which will remain correct independently of view rotation or scale:

func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    panRecognizer.setTranslation(panRecognizer.view.center, in: panRecognizer.view.superview)
}

func handlePanGesture(gesture: UIPanGestureRecognizer) {
    let translation = gesture.translation(in: gesture.view.superview)
    gesture.view.center = translation
}
like image 1
Eugene Dudnyk Avatar answered Nov 01 '22 22:11

Eugene Dudnyk