Search code examples
ioscocoa-touchcore-animation

Autoresizing frame of UILabel when animating frame (size) of parent UIView


I have a parent UIView that has child UIView (UILabel used in the code below) whose frame is set to the parent's bounds and whose autoresizingMask is set to flexible width and height:

UIView* parentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
UILabel* childLabel = [[UILabel alloc] initWithFrame:parentView.bounds];
childLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
childLabel.textAlignment = UITextAlignmentCenter;
childLabel.text = @"Hello";

I want to be able to animate the parent view's frame, specifically its size, and have the subview resize as part of the animation:

[UIView animateWithDuration:1.0 animations:^{ parentView.frame = CGRectMake(0, 0, 160, 240); }];

As a result of this animation I would want the text of the UILabel to animate along with the parent view's animation, so visually you'd see the text move from being centered at (160, 240) to (80, 120). However, instead of animating it appears the subview's frame is being immediately set to the value it should have at the end of the animation, so you see the position of the text immediately jump when the animation starts.

Is there a way to get subviews to autoresize as part of an animation?


Solution

  • I don't completely have my head around what's going on, but I think the core issue is that UIKit doesn't want to have to re-render the text every frame of the animation, so the contents of a UILabel aren't animatable. By default, the contentMode property of UILabel is UIViewContentModeRedraw, meaning that it'll redraw the UILabel at the target size as soon as the property is set.

    If you change the contentMode to UIViewContentModeCenter, the contents won't redraw and will remain centered in the UILabel.

    childLabel.contentMode = UIViewContentModeCenter;