Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom ease in animateWithDuration?

When doing UIView.animateWithDuration, I would like to define a custom curve for the ease, as opposed to the default: .CurveEaseInOut, .CurveEaseIn, .CurveEaseOut, .CurveLinear.

This is an example ease that I want applied to UIView.animateWithDuration:

let ease = CAMediaTimingFunction(controlPoints: Float(0.8), Float(0.0), Float(0.2), Float(1.0))

I tried making my own UIViewAnimationCurve, but it seems it accepts only one Int.

I can apply the custom ease to a Core Animation, but I would like to have custom easing for UIView.animateWithDuration for simpler and optimized code. UIView.animateWithDuration is better for me as I won't have to define animations for each animated property and easier completion handlers, and to have all animation code in one function.

Here's my non-working code so far:

let customOptions = UIViewAnimationOptions(UInt((0 as NSNumber).integerValue << 50))
UIView.setAnimationCurve(UIViewAnimationCurve(rawValue: 5)!)

UIView.animateWithDuration(2, delay: 0, options: customOptions, animations: {
        view.layer.position = toPosition
        view.layer.bounds.size = toSize
        }, completion: { finished in
            println("completion")
})
like image 257
brandon koopa Avatar asked Jul 08 '15 19:07

brandon koopa


3 Answers

That's because UIViewAnimationCurve is an enumeration - its basically human-readable representations of integer values used to determine what curve to use.

If you want to define your own curve, you need to use CA animations.

You can still do completion blocks and groups of animations. You can group multiple CA Animations into a CAAnimationGroup

let theAnimations = CAAnimationGroup()
theAnimations.animations = [positionAnimation, someOtherAnimation]

For completion, use a CATransaction.

CATransaction.begin()
CATransaction.setCompletionBlock { () -> Void in
    // something?
}
// your animations go here
CATransaction.commit()
like image 109
Chris Slowik Avatar answered Nov 15 '22 04:11

Chris Slowik


After a bunch of researches, the following code works for me.

  1. Create an explicit core animation transaction, set your desired timing function.
  2. Use eigher or both UIKit and CAAnimation to perform the changes.

    let duration = 2.0
    
    CATransaction.begin()
    CATransaction.setAnimationDuration(duration)
    CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(controlPoints: 0.8, 0.0, 0.2, 1.0))
    CATransaction.setCompletionBlock {
        print("animation finished")
    }
    
    // View animation
    UIView.animate(withDuration: duration) {
        // E.g. view.center = toPosition
    }
    
    // Layer animation
    view.layer.position = toPosition
    view.layer.bounds.size = toSize
    
    CATransaction.commit()
    
like image 3
夜一林风 Avatar answered Nov 15 '22 04:11

夜一林风


With iOS 10.0 you can use UIViewPropertyAnimator.

https://developer.apple.com/documentation/uikit/uiviewpropertyanimator

See https://developer.apple.com/videos/play/wwdc2016/216/

like image 2
Jonny Avatar answered Nov 15 '22 04:11

Jonny