简体   繁体   中英

Animate UIView frame with CALayer as subview

What I have:

I have aa hierarchy of UIView's and a CAGradientLayer that I use to set the "background colour" of this hierarchy. So I have something like this:

ViewA -> ViewB -> CAGradientLayer

What I am doing:

At one point, I want to animate the frame (only the height of it) of the ViewA. So it would be something like this:

[UIView animateWithDuration:timeInterval
                      delay:0
                    options:UIViewAnimationOptionCurveEaseIn
                 animations:^{
                              viewA.frame = newFrame;
}];

The issue:

The problem with this is that the CAGradientLayer won't animate it's frame, it simply change it's frame, and then the viewA starts animating as intended (this is clearly visible by setting the simulator to slow-motion animations).

What I tried:

I tried to do what Apple recommends here , by doing it inside the UIView animation block, but it didn't actually work, because I am still animating the frame here:

viewA.frame = newFrame;

I also understand that the I should animate the bounds, and not the frame of the CALayer , the problem is that, how can I animate the bounds and when animating the frame of the ViewA leave that CALayer out of the animation?

What I want:

I just want to animate the change of its height, so I would see both the viewA and the CAGradientLayer animating at the same time.

You'll have to understand that the UIView and CALayer hierarchy are different. Layout changes and animations operating on a UIView will not automatically affect the CALayer hierarchy.

So if you want changes applied to your view affect a layer you'll have to update that yourself.

Your code is also missing details. For example you claim you see your gradient layer change it's frame, but you don't show where you are changing it. Did you overwrite layoutSubviews somewhere to update it's frame ?

By default updating a layer frame will trigger it's implicit animations for the position & bounds properties. To change the speed of the animation you could use:

[CATransaction begin];
[CATransaction setAnimationDuration:10.0];
_myLayer.frame = newFrame;
[CATransaction commit]; 

First off, read this .

Try encapsulating your view animation code along with layer animation explicitly. Do not expect layer to animate automatically. Since you are dealing with positioning, you would need to change graidentlayer.bounds .

If that does not work, try this before your animation code:

[CATransaction begin];    
[CATransaction setDisableActions: NO];    
[CATransaction commit];

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