Benjammann
Benjammann

Reputation: 53

How do you create a Swift animation class that flips two images

I'm spending my turkey day trying to construct a flip animation class that I have been struggling with for weeks.

The goal is this:

Flip two images repeatedly, quickly at first, then slow down and stop, landing on one of the two images that was chosen before the animation began.

Right now both images are in a container view, in a storyboard. Ive tried using transitionFromView transitionFlipFromTop and I think that could work, but at the time I was unable to get it to repeat.

I am in the process of reading the View Programming Guide, but its tough to connect the dots between it, and swift. Being new to programming in general does not help.

Here is where I'm at: I'm now using a CATransform to scale an image from zero height, to full height. Im thinking that if I can somehow chain two animations, the first one showing the first image scaling up, then back down to zero, then animate the second image doing the same thing, that should give me the first part. Then if I could somehow get those two animations to repeat, quickly at first, then slow down and stop.

It seems I need to know how to nest multiple animations, and then be able to apply an animation curve to the nested animation.

I planned on solving the part about landing on a particular image by having two of these nested animations, one of them would have an odd number of flips, the other an even number of flips. Depending on the desired final image, the appropriate animation gets called.

Right now, my current code is able to repeatedly scale an image from zero to full, a set number of times:

import UIKit
import QuartzCore

let FlipAnimatorStartTransform:CATransform3D = {

    let rotationDegrees: CGFloat = -15.0
    let rotationRadians: CGFloat = rotationDegrees * (CGFloat(M_PI)/180.0)
    let offset = CGPointMake(-20, -20)
    var startTransform = CATransform3DIdentity
    startTransform = CATransform3DScale(CATransform3DMakeRotation(0, 0, 0, 0),
        1, 0, 1);

    return startTransform
    }()

class FlipAnimator {
    class func animate(view: UIView) {

        let viewOne = view
        let viewTwo = view

        viewOne.layer.transform = FlipAnimatorStartTransform
        viewTwo.layer.transform = FlipAnimatorStartTransform

        UIView.animateWithDuration(0.5, delay: 0, options: .Repeat, {
            UIView.setAnimationRepeatCount(7)

            viewOne.layer.transform = CATransform3DIdentity

        },nil)
    }
}

Im going to keep chipping away at it. Any help, or ideas, or hints about a better way to go about it would be amazing.

Thanks.

Upvotes: 0

Views: 2851

Answers (3)

David Rysanek
David Rysanek

Reputation: 979

I'm using this function to rotate image horizontally and to change the image during the transition.

private func flipImageView(imageView: UIImageView, toImage: UIImage, duration: NSTimeInterval, delay: NSTimeInterval = 0)
{
    let t = duration / 2

    UIView.animateWithDuration(t, delay: delay, options: .CurveEaseIn, animations: { () -> Void in

        // Rotate view by 90 degrees
        let p = CATransform3DMakeRotation(CGFloat(GLKMathDegreesToRadians(90)), 0.0, 1.0, 0.0)
        imageView.layer.transform = p

    }, completion: { (Bool) -> Void in

        // New image
        imageView.image = toImage

        // Rotate view to initial position
        // We have to start from 270 degrees otherwise the image will be flipped (mirrored) around Y axis
        let p = CATransform3DMakeRotation(CGFloat(GLKMathDegreesToRadians(270)), 0.0, 1.0, 0.0)
        imageView.layer.transform = p

        UIView.animateWithDuration(t, delay: 0, options: .CurveEaseOut, animations: { () -> Void in

            // Back to initial position
            let p = CATransform3DMakeRotation(CGFloat(GLKMathDegreesToRadians(0)), 0.0, 1.0, 0.0)
            imageView.layer.transform = p

        }, completion: { (Bool) -> Void in
        })
    })
}

Don't forget to import GLKit.

Upvotes: 2

Thiru
Thiru

Reputation: 1378

This flip animation swift code appears little better:

        let transition = CATransition()
        transition.startProgress = 0;
        transition.endProgress = 1.0;
        transition.type = "flip";
        transition.subtype = "fromRight";
        transition.duration = 0.9;
        transition.repeatCount = 2;
        self.cardView.layer.addAnimation(transition, forKey: " ")

Other option is

@IBOutlet weak var cardView: UIView!
var back: UIImageView!
var front: UIImageView!
self.front = UIImageView(image: UIImage(named: "heads.png"))
self.back = UIImageView(image: UIImage(named: "tails.png"))
self.cardView.addSubview(self.back)
UIView.transitionFromView(self.back, toView: self.front, duration: 1, options: UIViewAnimationOptions.TransitionFlipFromRight , completion: nil)

Please check link

Upvotes: 1

matt
matt

Reputation: 534925

It seems I need to know how to nest multiple animations, and then be able to apply an animation curve to the nested animation.

I don't think so. I don't think you want/need to nest anything. You are not repeating an animation in this story; you are doing different animations each time (because the durations are to differ). This is a sequence of animations. So I think what you need to know is how to do either a keyframe animation or a grouped animation. That way you can predefine a series of animations, each one lasting a certain predefined duration, each one starting after the preceding durations are over.

And for that, I think you'll be happiest at the Core Animation level. (You can't make a grouped animation at the UIView animation level anyway.)

Upvotes: 0

Related Questions