Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIVIew animation - Scaling + Translating

I have a view which I want to be scaled and translated to a new location by animating it. I tried to achieve it with the following code:

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kDurationForFullScreenAnimation];
[[self animatingView] setFrame:finalRect];
[UIView commitAnimations];

The effect of this code is, the view first changes its content's size to the finalRect and then translates it to the new location. i.e. The scaling part is never animated. The view is just transformed to the new size and then translated.

This issue is already discussed in several other threads but none of them draw a conclusion. A solution does exist though, to use a timer and set the frame each time in the timer callback, but it has a performance drawback.

What is the most appropriate solution to this problem, also, why in first case this problem occur?

Thanks

like image 225
Raj Pawan Gumdal Avatar asked Aug 18 '10 06:08

Raj Pawan Gumdal


2 Answers

Try this solution :

  CGAffineTransform s =  CGAffineTransformMakeScale(0.5f,0.5f);
  CGAffineTransform t = CGAffineTransformMakeTranslation(100, 0);
  v2.transform = CGAffineTransformConcat(t,s); // not s,t

this operation is not commutative. The order is the opposite of the order when using convenience functions for applying one transform to another.

And you can use this operation to : for example (remove the Scale) :

    v2.transform =
    CGAffineTransformConcat(CGAffineTransformInvert(s), v2.transform);
like image 86
user3391686 Avatar answered Oct 16 '22 01:10

user3391686


Setting the frame does neither a scale nor a translation. You are either using the wrong terminology or you are using the wrong tool for the job. Scale and translate are both done using Core Graphics Affine transforms when you're looking to affect the UIView (as opposed to the layer which use Core Animation transforms).

To scale a view use

// 2x
[rotationView setTransform:CGAffineTransformMakeScale(2.0, 2.0)];

To translate, use

// Move origin by 100 on both axis
[rotationView setTransform:CGAffineTransformMakeTranslation(100.0, 100.0)];

To animate these, wrap them in an animation block. If you want to transform the view with both of these, then you need to concatenate them.

If you are not wanting scale and translation (transforms) at all, then what you mean is you want to change the view's bounds and position. These are changed with calls to

[view setBounds:newRect];
[view setCenter:newCenter];

Where newRect and newCenter are a CGRect and CGPoint respectively that represent the new position on the screen. Again, these need wrapped in an animation block.

like image 22
Matt Long Avatar answered Oct 16 '22 01:10

Matt Long