Scale/Animate One Side of UIView to Be Smaller? - CGAffineTransformMakeScale - ios

I would like to animate a UIView so its right side becomes smaller and then back again. This animation will trigger when a UIButton in this UIView is tapped. Here is a quick mockup of what I would like - the UIView will go from state 1 > state 2 > state 1:
It looks like it is being pushed on one side.
Here is the code I have for another action - this makes the UIView smaller and larger again as if it is being pushed on the centre, rather than the side.
self.myView.transform = CGAffineTransformMakeScale(0.95,0.95);
self.myView.alpha = 1.f;
[UIView beginAnimations:#"button" context:nil];
[UIView setAnimationDuration:0.5];
self.myView.transform = CGAffineTransformMakeScale(1,1);
self.myView.alpha = 1.0f;
[UIView commitAnimations];
How do I apply this same effect but only to the right side? Any help would be much appreciated, thanks!

According to this question u need t make Perspective Transform for example, i modified a bit from that question i linked
CATransform3D perspectiveTransform = CATransform3DIdentity;
perspectiveTransform.m34 = 1.0 / -500;
perspectiveTransform = CATransform3DRotate(perspectiveTransform, 40.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
[UIView animateWithDuration:0.4 animations:^{
self.myView.layer.transform = perspectiveTransform;
}];
EDIT 2 Brings back to original
- (void)startAnimation:(id)sender
{
CATransform3D perspectiveTransform = CATransform3DIdentity;
perspectiveTransform.m34 = 1.0 / -500;
perspectiveTransform = CATransform3DRotate(perspectiveTransform, 40.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
[UIView animateWithDuration:1.4 animations:^{
self.myView.layer.transform = perspectiveTransform;
}completion:^(BOOL finished) {
CATransform3D originalPerspectiveTransform = CATransform3DIdentity;
[UIView animateWithDuration:0.9 animations:^{
self.myView.layer.transform = originalPerspectiveTransform;
}];
}];
}

Related

CATransform3DRotate effects gone after applying anchor point

EDIT with correct observation.
I used the following two snippets to rotate an UIImageView. After the stage1, I got the desired 3D effect: the view rotate (3D effect) and stretched out (larger size). On stage2, I am trying to swing the rightView with the hinge on the right.
If I applied the line that changes the anchor point, the view swings correctly (hinge on right) with one major issue: The view's size got restored back to original size (smaller) while the (rotation) 3D effect is still intact and then the swinging occurs.
Any suggestions?
rightView.layer.anchorPoint = CGPointMake(1.0, 0.5);
-(void)stage1
{
[UIView animateWithDuration:1.5 animations:^{
rightView.transform = CGAffineTransformMakeTranslation(0,0); //rightView i UIImageView
CATransform3D _3Dt = CATransform3DIdentity;
_3Dt =CATransform3DMakeRotation(3.141f/42.0f,0.0f,-1.0f,0.0f);
_3Dt.m34 = -0.001f;
_3Dt.m14 = -0.0015f;
rightView.layer.transform = _3Dt;
} completion:^(BOOL finished){
if (finished) {
NSLog(#"finished..");
}
}];
}
-(void)Stage2
{
rightView.layer.anchorPoint = CGPointMake(1.0, 0.5); //issue?
rightView.center = CGPointMake(1012, 384);
[UIView animateWithDuration:1.75 animations:^{
CATransform3D rightTransform = rightView.layer.transform;
rightTransform.m34 = 1.0f/500;
rightTransform = CATransform3DRotate(rightTransform, M_PI_2, 0, 1, 0);
rightView.layer.transform = rightTransform;
} completion:^(BOOL finished) {
}];
}
You need to add the "options" to your animate with duration and add options:UIViewAnimationOptionBeginFromCurrentState
Otherwise it starts from the beginning again.
So your stage 2 would look like this:
-(void)Stage2
{
rightView.layer.anchorPoint = CGPointMake(1.0, 0.5); //issue?
rightView.center = CGPointMake(1012, 384);
[UIView animateWithDuration:1.75
delay:0.00
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
CATransform3D rightTransform = rightView.layer.transform;
rightTransform.m34 = 1.0f/500;
rightTransform = CATransform3DRotate(rightTransform, M_PI_2, 0, 1, 0);
rightView.layer.transform = rightTransform;
} completion:^(BOOL finished) {
}];
}

CGAffineTransform rotation and resize on slider value

I am using Slider to Resize and Rotate-
For the Rotate -
CGAffineTransform transform = editingView.transform;
transform = CGAffineTransformMakeRotation(sliderVal * 2*M_PI / 30);
editingView.transform = transform;
For the Resize-
CGAffineTransform t = CGAffineTransformMakeScale(sliderVal/30, sliderVal/30);
CGPoint center = editingView.center;
[UIView animateWithDuration:0.5
animations:^{
editingView.transform = t;
editingView.center = center;
}
completion:^(BOOL finished) {
}];
Using the above code,Both working fine separately.
But I have to resize the rotated view,Or rotate the resized view.
I saw many suggestions coming separate behavior because i am using CGAffineTransformMakeRotation,CGAffineTransformMakeScale,If i use the CGAffineTransformScale,CGAffineTransformRotation then my problem will be solve.
The problem is when I am using CGAffineTransform then scaling is not proper,View disappears from the screen.
You're setting transformation matrix of the view with editingView.transform line.
You should change your code for rotate:
CGAffineTransform transform = editingView.transform;
transform = CGAffineTransformMakeRotation(sliderVal * 2*M_PI / 30);
editingView.transform = CGAffineTransformConcat(editingView.transform, transform);
and for resize:
CGAffineTransform t = CGAffineTransformMakeScale(sliderVal/30, sliderVal/30);
CGPoint center = editingView.center;
[UIView animateWithDuration:0.5
animations:^{
editingView.transform = CGAffineTransformConcat(editingView.transform,t);
editingView.center = center;
}
completion:^(BOOL finished) {
}];
With CGAffineTransformConcat you add 2 transform matrixes together so you won't lose older transforms. You can use CGAffineTransformIdentity to reset the transform.
CGAffineTransform translate = CGAffineTransformMakeTranslation(self.webView.frame.origin.x,self.webView.frame.origin.y - self.webView.frame.size.height * 0.25);
CGAffineTransform scale = CGAffineTransformMakeScale(0.6, 0.6);
CGAffineTransform transform = CGAffineTransformConcat(translate, scale);
transform = CGAffineTransformRotate(transform, degreesToRadians(-10));
[UIView beginAnimations:#"MoveAndRotateAnimation" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:2.0];
editingView.transform = transform;
[UIView commitAnimations];
Try like this...

Animating a scaling view from a corner (zooming in)

I'm trying to scale my view like so:
CGRect endFrame = self.detailView.bounds;
[UIView animateWithDuration:0.25 animations:^{
self.descriptionButton.bounds = endFrame;
}completion:^(BOOL finished) {
self.containerView.alpha = 0.0;
self.detailView.alpha = 1.0;
}];
My detailView is the container view. My descriptionButton is in the upper left corner. I want to give a zoom in type effect by having the button take up the whole screen. However, by default Core Animation scales from the anchor point at its center.
I tried setting the anchor point to the lower right corner of the view's layer like this:
self.descriptionButton.layer.anchorPoint = CGPointMake(self.descriptionButton.bounds.size.width, self.descriptionButton.bounds.size.height);
CGRect endFrame = self.detailView.bounds;
[UIView animateWithDuration:0.25 animations:^{
self.descriptionButton.bounds = endFrame;
}completion:^(BOOL finished) {
self.containerView.alpha = 0.0;
self.detailView.alpha = 1.0;
}];
But when I do that, I don't see any animation at all. Any thoughts? Thanks.
You can just use a little math
CGRect endFrame = self.detailView.frame;
CGRect currentFrame = self.detailView.frame;
[UIView animateWithDuration:0.25 animations:^
{
self.descriptionButton.frame = CGRectMake(currentFrame.x - (endFrame.size.width - currentFrame.size.width), currentFrame.y - (endFrame.size.height - currentFrame.size.height), endFrame.size.width, endFrame.size.height);
}
completion:^(BOOL finished)
{
self.containerView.alpha = 0.0;
self.detailView.alpha = 1.0;
}];
The anchorPoint property is "normalized" to values from 0 to 1. 0.5, 0.5 is the center. 0,0 is top left. 1,1 is bottom right.
Your code is setting the anchorPoint property using pixel coordinates, which is wrong. I don't know what it would do, but it's wrong.

ios CATransform3DMakeScale scaleup animation

I have the following animation:
CATransform3D scaleTransform = CATransform3DMakeScale(0.1,0.1, 1.0);
scaleAnimation.toValue = [NSValue valueWithCATransform3D:scaleTransform];
keyframeAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];;
where I'm scaling down a subview. But I'm trying to do opposite. start from .01% of the size of the subview and go to 100% of the size of the subview. Does anyone knows how can I do this?
Do this:
yourSubView.transform = CGAffineTransformMakeScale(0.01, 0.01);
[UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
//change time duration according to requirement
// animate it to the identity transform (100% scale)
yourSubView.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished){
// if you want to do something once the animation finishes, put it here
}];

animated popup view similar to one in Ipad music folder

I would like to know what is the name of the functionality that is used in the Ipad's Music folder, where when an album folder is clicked, details regarding that album pops up in an animated view.
I tried using presentModelViewController but its functionality is different.
It would be great if someone could help me out.
I just managed to get sth. like this to work using CoreAnimation / QuartzCore Framework...
be sure to
#import <QuartzCore/QuartzCore.h>
when you want to animate, use CATransform3Dand the poorly documented CATransform3D.m34 property. this will do the first half of the animation (assuming 200x200<->450x450 with 180° rotation):
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDelegate:self];
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -1000; // this turns on perspective!
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 90.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
someView.layer.transform = rotationAndPerspectiveTransform;
someView.bounds = CGRectMake(0, 0, 325, 325);
[UIView commitAnimations];
for the second half of the animation, you have to add/remove your view to the hierarchy. this example shows hiding/showing of a view that already exists as a subview of someView, it also makes use of a BOOL isUp instance variable (the first half of the aniation is independent of the isUp-flag!)
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if (flag) {
if (isUp) {
someSubView.hidden = YES; // hide subview
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CATransform3D rotationAndPerspectiveTransform = CATransform3DRotate(someView.layer.transform, -90.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
someView.layer.transform = rotationAndPerspectiveTransform;
someView.bounds = CGRectMake(0, 0, 200, 200);
[UIView commitAnimations];
isUp = NO;
} else {
someSubView.hidden = NO; // Show subview
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CATransform3D rotationAndPerspectiveTransform = CATransform3DRotate(someView.layer.transform, 90.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
someView.layer.transform = rotationAndPerspectiveTransform;
someView.bounds = CGRectMake(0, 0, 450, 450);
[UIView commitAnimations];
isUp = YES;
}
}
}
one last thing: everything in your view will appear mirrored, it might not be the ideal solution, but mirroring back by applying a CGAffineTransform to the subview does the trick:
- (void)viewDidLoad
{
[super viewDidLoad];
someSubView.transform = CGAffineTransformMakeScale(-1, 1);
isUp = NO;
}
i'm alredy a month late with this solution but i hope it helped someone :)
i first tried using the animateWithDuration:animations:completion: block-based API but that turned out to lag heavily (no smooth first/second-half animaiton even without touching subviews).
On the iPad you have several different options with regards to animating a modal view controller, you can find them here: UIModalTransitionStyle.
However, if you are referring to the "zoom and flip" sort of effect on the album I'm pretty sure this is private behaviour so you would need to develop this yourself.... you might be able to accomplish this with Core Graphics/Quartz.

Resources