10
votes

Example screen capture:

http://i.stack.imgur.com/CyOQi.gif

What is a better way to animate the resizing of a UIView that includes subviews?

My current method:

In the screen capture, the parent UIView (orange) has a subview UILabel (yellow + autoresizing). animateWithDuration is animating the resizing of the parent UIView's frame. The problem with this method is it does not animate the resizing of the subview. It abruptly changes, where it should scale animatedly.

Is explicitly animating the subview best, or is there a more efficient method? (e.g. CGAffineTransform?)

Sample code:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.parentView = [[UIView alloc] initWithFrame:CGRectMake(10, 100, 200, 200)];
    self.parentView.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:self.parentView];

    self.childLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 180, 180)];
    self.childLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth |
                                     UIViewAutoresizingFlexibleHeight;
    self.childLabel.backgroundColor = [UIColor yellowColor];
    [self.parentView addSubview:self.childLabel];

    [NSTimer scheduledTimerWithTimeInterval:2
                                     target:self
                                   selector:@selector(randomizeParentViewSize)
                                   userInfo:nil
                                    repeats:YES];
}

- (void)randomizeParentViewSize {
    CGFloat width = arc4random_uniform(100) + 50;
    CGFloat height = arc4random_uniform(100) + 50;

    [UIView animateWithDuration:1.5f
                          delay:0.0f
                        options:0
                     animations:^{
                         self.parentView.frame = CGRectMake(10, 50 + height, width, height);
                     }
                     completion:^(BOOL finished) {
                     }];
}
3
No, the subview should animate. Show more about your animation code please. Also please describe the autoresizing or autolayout constraints of the subview.matt
Matt, I added the code to my question. When the orange parent view's frame changes, it animates, but the subview does not.Justin
Found an explanation: The child UILabel does not animate by default because its default content mode is UIViewContentModeRedraw: stackoverflow.com/questions/1729596/…Justin
It's been a few years, but after suffering hours of frustration my animation problem was solved by your explanation here re content mode. In my case, it wasn't a UILabel, but rather an ARSCNView. Its default content mode was .center; switching to .scaleToFill solved my issue. So, THANKS!!Dave Goldman

3 Answers

3
votes

To animate the view and also the subview you could use this code:

[UIView animateWithDuration:0.5f animations:^{
        self.testView.transform = CGAffineTransformMakeScale(0.5, 0.5);
    }];

More Info

You can't use frame, bounds, or center if you are also animating things using CGAffine, So if you also need to move the view use something like this:

    CGAffineTransform transform = CGAffineTransformMakeTranslation(150,400);
    transform = CGAffineTransformScale(transform, 0.5, 0.5);
3
votes

I Guess Your Yellow SubView is UILabel ?

When UILabel change frame size in UIViewAnimation will scale Immediately

unless you use the CGAffineTransformScale


some example

when

[self.view addSubview:view_parent];
[view_parent addSubview:view_component];

if both view_parent and view_component is UIView

[UIView animateWithDuration:2.0 animations:^{
    [view_parent setFrame:CGRectMake(0, 20, 160, 160)];
    [view_component setFrame:CGRectMake(20, 20, 80, 80)];
}];

is work fine

but when view_parent is UIView and view_component is UILabel

you need do something like ...

[UIView animateWithDuration:2.0 animations:^{
    [view_parent setFrame:CGRectMake(0, 20, 160, 160)];
    view_component.transform = CGAffineTransformScale(view_component.transform, 0.5, 0.5);
    [view_component setFrame:CGRectMake(20, 20, 80, 80)];
}];

Wish help ~

1
votes

Use UIViewAnimationOptionLayoutSubviews:

  1. Add proper leading, trailing, top and bottom constraints on the subview.
  2. [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{ //resize the superview } completion:nil];