Search code examples
objective-ccgaffinetransform

Using cgaffinetransformmakescale and cgaffinetransformmakerotation deforms my view


I have a simple UIView:

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
view.backgroundColor = [UIColor greenColor];
[self.view addSubview:view];
self.someView = view;

Then I do this

[UIView animateWithDuration:10
                      delay:1
                    options:UIViewAnimationOptionCurveEaseInOut
                 animations:^{
    self.someView.center = CGPointMake(CGRectGetWidth(self.view.bounds) - CGRectGetWidth(self.someView.frame) / 2, 150);

                     CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI);
                     self.someView.transform = CGAffineTransformScale(transform, 2, 0.5);

}
                 completion:^(BOOL finished) {

                 }];

While is executed this simple animation, someView is deformed. As far as I know it should rotate and change it's size. I can't understand why is it happening so, how can i fix it?

Thanks


Solution

  • The problem is animating a combined scaling and rotation. The end result is the same as animating them separately, but the frames in between are not easily defined. So the animation framework makes a guess, and it is not what you are expecting.

    If you want the animation to show a rotation and scaling separately, you need to apply them separately to the view hierarchy. For example:

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    view.backgroundColor = [UIColor greenColor];
    [self.view addSubview:view];
    self.someView = view;
    
    UIView *innerView = [[UIView alloc] initWithFrame:view.bounds];
    innerView.backgroundColor = [UIColor blueColor];
    [view addSubview:innerView];
    self.someInnerView = innerView;
    

    The animation splits the transform:

    [UIView animateWithDuration:10
                          delay:1
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                         self.someView.center = CGPointMake(CGRectGetWidth(self.view.bounds) - CGRectGetWidth(self.someView.frame) / 2, 150);
    
                         self.someView.transform = CGAffineTransformMakeRotation(M_PI);
                         self.someInnerView.transform = CGAffineTransformMakeScale(2, 0.5);
    
                     }
                     completion:^(BOOL finished) {
    
                     }];