Change the duration (speed) in the current animation

I make an endless rotation animation that works great when I first launch it. What I wanted to achieve was the ability to change the rotation speed at runtime. I have this function in the animation:

-(void)startBlobAnimation:(float)deltaT
{
    [UIView beginAnimations:@"Spinning" context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    [UIView setAnimationDuration:deltaT];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationRepeatCount:FLT_MAX];

    CGAffineTransform rotation = CGAffineTransformMakeRotation(-symmetryAngle);
    blobView.transform = rotation;

    // Commit the changes and perform the animation.
    [UIView commitAnimations];
}

Calling with different deltaT values ​​after the start of the animation has no effect. If I add [wheelView.layer removeAllAnimations];a function at the beginning, it will successfully stop the animation, but will not restart it. I also tried using the block command to start the animation with the same result. At the moment, I do not understand at all. Can anyone explain what the problem is? Thank!

+2
source share
3 answers

, , , . . : anim.keyPath - Nil ( ). , , . , , : symmaAngle - , , , 72 5- .

-(void)startWheelsAnimation:(float)deltaT
{
    float startingAngle = 0.0;

    if(isAnimating) {
        // If animation is in progress then calculate startingAngle to
        // reflect the current angle of rotation
        CALayer *presLayer = (CALayer*)[blobView.layer presentationLayer];
        CATransform3D transform = [presLayer transform];
        startingAngle = atan2(transform.m12, transform.m11);
    }

    isAnimating = YES;

    // Restart the animation with different duration, and so that it starts
    // from the current angle of rotation
    CABasicAnimation * anim = [ CABasicAnimation animationWithKeyPath:@"transform.rotation.z" ] ;
    anim.duration = deltaT;
    anim.repeatCount = CGFLOAT_MAX;
    anim.fromValue = @(startingAngle);
    anim.toValue = @(startingAngle - symmetryAngle) ;
    [blobView.layer addAnimation:anim forKey:anim.keyPath];
}
+1

2017

CA .

" Alex"...

...

@IBDesignable
class SpinningThing: UIView {

    public func runAnimation() { // call this from the view controller, say
        speedy = 1.0
        startFastThenSlowDown()
    }


    override func layoutSubviews() {

        super.layoutSubviews()
        setup()
    }

    func setup() {

        setup .. other stuff (draw things)
        setupThingThatSpins()
    }

    var thingThatSpins = CAShapeLayer()

    var speedy = 0.5        // start fast
    var finalSpeed = 13.0   // final slow speed

    func setupThingThatSpins() {

        let p = UIBezierPath( .. etc etc
        thingThatSpins.strokeColor .. etc etc
        // so actually draw the thingThatSpins
    }

startFastThenSlowDown...

func startFastThenSlowDown() {

    speedy *= 1.175
    animeSpinRestartable(spr: speedy)
    if speedy < finalSpeed {
        delay(0.1) { self._slowDown() }
    }
}

, Alex...

func animeSpinRestartable(spr: CFTimeInterval) {

    let _key = "animeSpinRestartable"

    thingThatSpins.removeAnimation(forKey: _key)
    // is safe the first time through

    // get the current angle...
    let t3 = arcs.presentation()?.transform
    let cur = (t3 == nil) ? 0 : atan2(t3!.m12, t3!.m11)

    let r = _typicalAnim(keyPath: "transform.rotation.z")
    r.fromValue = cur
    r.toValue = cur + 2 * CGFloat.pi
    r.duration = spr

    ///r.isCumulative = true ?  seems unnecessary, so don't do it

    thingThatSpins.add(r, forKey: _key)
}

thingThatSpins ( ), - ( , !)

, OP.

+1

-

  • , API CoreAnimation. ( , UIViewAnimationOptionRepeat)

  • , , ( , )

  • layer.speed

Here is a working example. Create a new “empty” iOS project in Xcode and replace AppDelegate as follows:

@interface AppDelegate ()
@property ( nonatomic, strong ) UIView * animationView ;
@end

@implementation AppDelegate

-(void)buttonClicked
{
    self.animationView.layer.speed = 3.0 - self.animationView.layer.speed ;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    CGRect bounds = self.window.bounds ;
    {
        UIView * subview = [ [ UIView alloc ] initWithFrame:(CGRect){ .size = { 100, 100 } } ] ;
        [ self.window addSubview:subview ] ;

        subview.backgroundColor = [ UIColor orangeColor ] ;
        subview.center = (CGPoint){ CGRectGetMidX( bounds ), CGRectGetMidY( bounds ) } ;

        CABasicAnimation * anim = [ CABasicAnimation animationWithKeyPath:@"transform.rotation.z" ] ;
        anim.duration = 1.0 ;
        anim.repeatCount = CGFLOAT_MAX ;
        anim.fromValue = @0.0 ;
        anim.toValue = @(2.0*M_PI) ;

        [ subview.layer addAnimation:anim forKey:nil ] ;

        self.animationView = subview ;
    }

    UIControl * button = [[ UIControl alloc ] initWithFrame:bounds ] ;
    [ button addTarget:self action:@selector( buttonClicked ) forControlEvents:UIControlEventTouchUpInside ] ;

    [ self.window addSubview:button ] ;


    return YES;
}

@end
-1
source

All Articles