简体   繁体   中英

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

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

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?

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)
    }
}

The problem I see is that translation is retrieved like gesture.translation(in: view) , eg 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
}

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)
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM