Coreanimation - Opacity Fade in and Out Animation Not Working

CoreAnimation - Opacity Fade In and Out Animation Not Working

I'm faced the same issue and the problem is - one layer can't contain fade in and out.
So you can add the other animation to the parent layer as i did

CALayer *parentLayer = [CALayer layer];
CALayer *animtingLayer = [CALayer layer];

//FADE IN
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.beginTime = CMTimeGetSeconds(img.startTime);
animation.duration = CMTimeGetSeconds(_timeline.transitionDuration);
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeBoth;
animation.additive = NO;
[parentLayer addAnimation:animation forKey:@"opacityIN"];

//FADE OUT
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.beginTime = CMTimeGetSeconds(CMTimeAdd(img.passTimeRange.start, img.passTimeRange.duration));
animation.duration = CMTimeGetSeconds(_timeline.transitionDuration);
animation.fromValue = [NSNumber numberWithFloat:1.0f];
animation.toValue = [NSNumber numberWithFloat:0.0f];
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeBoth;
animation.additive = NO;
[animtingLayer addAnimation:animation forKey:@"opacityOUT"];

[parentLayer addSublayer:animtingLayer];

how to create a fade in / fade out animation that can stopped in the middle, without jumping to end of animation?

The UIView animateWithDuration methods create Core Animation objects on layers under the covers to make the animation work. The CAAnimation animates a presentationLayer of the view's layer. You can query the presentation layer to get the state of the animation while it is in progress.

Here's what I would suggest:

Use animateWithDuration:animations: as you are doing now.

If you need to stop the animation in mid-flight, get the view's layer's presentation layer, and capture the value of the alpha property.

Then set the view's opacity the "in-flight" value and send a removeAllAnimations message to the layer. That will have the effect of stopping the animation at it's current state.

Finally, invoke a new animateWithDuration:animations: statement with your new reverse animation.

CoreAnimation fades out layers and moves a copy instead of just moving the layer

After typing this question and thinking some more about the problem I found a solution or workaround. Instead of directly removing a layer I set it to hidden and skip hidden layers in my layout loop. Then after all the animations are done (in the completion block of my CATransaction) I remove all the hidden layers without animation.

iOS animateWithDuration complete immediately for hidden/show or even opacity

The problem is that UIView animations are meant for animating views.

A high overview of what's happening when you use UIView animations is that the block gets executed, which changes the properties of the view which in turn changes the backing layer (or changes the layer properties directly). When the (backing) layer's properties changes it asks its delegate (which always is the view if the layer is backing a view) to provide an action for that animation. The view can then check if the change happened inside of an animation block or not. If the change happened inside of an animation block, the view will return an animation with the correct duration, timing curve, etc.

However, for view's that aren't attached to a layer, there is no delegate to ask. Instead the layer continues to look for an "action" (a more general term for an animation) and eventually ends up picking the default action for that layer class. This behavior is outlined in the documentation for the -actionForKey: method on CALayer.

The default action is almost always (animations of paths being one exception) a 0.25 second long basic animation. This is the animation you are seeing. Layers actually animate their changes by default (it's a view behavior to disable this) so you would see this animation both from changes inside the animation block and form outside the animation block.



If you want to read more about this:

The first third of my objc.io article here explain the interaction between the view and the layer more closely. I also have a blog post here that among other things explain the difference between implicit and explicit animations.


The above explains why you are seeing this behavior. To "fix" it you would either go to a higher abstraction and use a view instead of a layer or you would create the animation objects yourself and add them to the layer (the work that UIKit is doing at the view level).

Core animation stops when the Master of the split viewcontroller hide (in portrait mode)?

Yes, the animations are removed from the view's layer once its view controller is hidden. Strangely, sometimes the animation can persist even if view.layer.animationKeys.count == 0, but usually not.

Your best bet is to start the animations in -viewWillAppear: or -viewDidAppear:... for @vignesh_kumar, perhaps through a method like:

- (void)startAnimations
{
NSArray *visibleCells = self.tableView.visibleCells;
for (CustomTableViewCell *cell in visibleCells) {
[cell animateIfNeeded];
}
}

@doNotCheckMyBlog, here you could call the method that starts the headerView's animation.

In addition to that, I'm guessing that the animations will also be stopped if you background the app and then resume it.

You will also need to call the -startAnimations method when the app resumes. For example, your app delegate could send out an NSNotification in its -applicationDidBecomeActive: or -applicationWillEnterForeground: method. Your MasterViewController could observe this notification and call -startAnimations when it receives it.

If you don't need to return to the same exact state in the animation, then this shouldn't be a huge problem. If you need to return to the same state in the animation as it was in when the app was backgrounded, then you'll also need to save the state and then set the initial state when you restart the animation.

animateWithDuration - FadeIn/FadeOut animation in UITextField

Make 2 labels, 1 for the old score 1 for the new, this way both can be done in 1 animation, and in the completion, set the new score to the oldScoreLabel so the other one is ready when ether you'll update the score.

you should get something like this:

 UIView.animateWithDuration(0.6, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.scoreOutlet.alpha = 0.0

self.newScoreOutlet.text = "\(self.numberFormatter.stringFromNumber(self.score)!)"
self.newScoreOutlet.transform = CGAffineTransformMakeScale(1.5, 1.5)
self.newScoreOutlet.alpha = 1.0

}) { (_) in
UIView.animateWithDuration(0.0, animations: {

self.newScoreOutlet.transform = CGAffineTransformMakeScale(1.0, 1.0)
self.newScoreOutlet.alpha = 0.0

self.scoreOutlet.alpha = 1.0
self.scoreOutlet.text = self.newScoreOutlet.text
})
}


Related Topics



Leave a reply



Submit