Get Labels Animation Same as Phibrow App
Asked Answered
E

3

8

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?

Epileptoid answered 26/12, 2017 at 7:38 Comment(1)
Refer raywenderlich.com/162745/…Adlare
L
2

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)
    }
}
Limey answered 15/1, 2018 at 9:38 Comment(1)
@meet-doshi try the above code and let me know if it didn't work for you.Limey
R
1

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
}
Rondelet answered 1/1, 2018 at 7:57 Comment(0)
M
1

Perhaps problem in order. You are applying translation after applying rotation. On transform that rotated. It means that your destination object will be rotated, and then translated according to ration. So if you rotate object on Float.Pi and try to move object it will move in opposite direction. Instead you had to move object first and then apply existed transform.

@IBAction func panRecognised(_ gesture: UIPanGestureRecognizer) {
    if gesture.state == .began || gesture.state == .changed{
        guard let targetView = gesture.view else { return }
        let transform =  targetView.transform
        let translation = gesture.translation(in: view)
        targetView.transform = transform.concatenating(CGAffineTransform(translationX: translation.x, y: translation.y))
        gesture.setTranslation(CGPoint(x: 0, y: 0), in: view)
    }
}
Mandatory answered 4/1, 2018 at 10:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.