A better way to animate resizing of UIView and sub

2020-06-03 06:43发布

问题:

Example screen capture:

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) {
                     }];
}

回答1:

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 ~



回答2:

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:

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];