Darkening UIView while flipping over using UIViewAnimationTransitionFlipFromRight - iphone

I'm using a standard animation block to flip over from one view to another, like this:
[UIView beginAnimations:#"FlipAnimation" context:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO];
[UIView setAnimationBeginsFromCurrentState:NO];
[containerView exchangeSubviewAtIndex:1 withSubviewAtIndex:0];
[UIView commitAnimations];
During the animation's course, the "from" view darkens as it begins to flip over. Since I'm using nearly identical views on both sides which don't cover the whole view (it's meant to represent a physical card being flipped over), this looks absolutely horrible. Using [UIColor clearColor] as the backgroundColor property for every associated UIView didn't help one bit as transparent areas seem to get darkened as well.
Any ideas on how I could get rid of this darkening effect?

Seems you have to do the animation 'by hand', using Core Animation transforms.
I divided the Animation in two parts. First I rotate 'viewOne' half the way with animation and 'viewTwo' half the way in the other direction without animation.
When the first half of the animation is done, I do the rest in the delegate method.
Yours parameters may vary :)
Skewing is courtesy of some other StackOverflow answer I found.
- (IBAction)flip:(id)sender
{
UIView* viewOne = [self.view.subviews objectAtIndex:0];
UIView* viewTwo = [self.view.subviews objectAtIndex:1];
viewOne.hidden = YES;
CATransform3D matrix = CATransform3DMakeRotation (M_PI / 2, 0.0, 1.0, 0.0);
CATransform3D matrix2 = CATransform3DMakeRotation (-M_PI / 2 , 0.0, 1.0, 0.0);
matrix = CATransform3DScale (matrix, 1.0, 0.975, 1.0);
matrix.m34 = 1.0 / -500;
matrix2 = CATransform3DScale (matrix2, 1.0, 0.975, 1.0);
matrix2.m34 = 1.0 / -500;
viewOne.layer.transform = matrix2;
[UIView beginAnimations:#"FlipAnimation1" context:self];
[UIView setAnimationDuration:1];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationPartOneDone)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
viewTwo.layer.transform = matrix;
[UIView commitAnimations];
}
-(void)animationPartOneDone
{
UIView* viewOne = [self.view.subviews objectAtIndex:0];
UIView* viewTwo = [self.view.subviews objectAtIndex:1];
viewOne.hidden = NO;
viewTwo.hidden = YES;
CATransform3D matrix = CATransform3DMakeRotation (2 * M_PI, 0.0, 1.0, 0.0);
matrix = CATransform3DScale (matrix, 1.0, 1.0, 1.0);
[UIView beginAnimations:#"FlipAnimation2" context:self];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
viewOne.layer.transform = matrix;
[UIView commitAnimations];
[self.view exchangeSubviewAtIndex:1 withSubviewAtIndex:0];
}

Related

ios growth animation CGAffineTransformMakeScale moves around

I am animating a tree that grows. Like a Tree, I want my UIImage to stay in the same place, so that when I scale it up it appears to grow.
Right now its jumping around, i.e. its growing from the centre - I need it to grow from the bottom.
Is there a way to set the origin/base of the animation. So the scale animation works from the bottom.
Hope that makes sense. here is my code:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
tree.transform = CGAffineTransformMakeScale(1.0f, 1.25f);
[UIView commitAnimations];
You may wish to look at the CALayer class for this and set the anchorPoint to the centerbottom
- (void)viewDidLayoutSubviews
{
self.outletTestView.layer.anchorPoint = CGPointMake(0.5, 1.0);
self.outletTestView.layer.position = CGPointMake(100, 300);
}
Don't forget to include:
#import <QuartzCore/QuartzCore.h>
And use for the scaling:
CGAffineTransform CGAffineTransformScale ( CGAffineTransform t, CGFloat sx, CGFloat sy );
Like so:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
tree.transform = CGAffineTransformScale(tree.transform, 1.0f, 1.25f);
[UIView commitAnimations];

Animate a UIImageView from center of the UIImageView

I have a UIImageView that should animate from size (0,0) --> (93,75)
I have the following
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionNone
animations:^{
imgButton.layer.anchorPoint = CGPointMake(imgButton.bounds.size.width/2, imgButton.bounds.size.height/2);
CGRect btnFrame = imgButton.frame;
btnFrame.size.width = 105;
btnFrame.size.height = 85;
imgButton.frame = btnFrame;
}
completion:^(BOOL finished) {
[self animageButton2:imgButton];
}];
This is working but the only problem I have is that it is not animating from the center of the UIImageView but from the top left corner.
Anybody got a clue?
I've solved it with the help of Borrden. This is what my solution was.
First create an imageview
UIImageView *imgLineup = [[UIImageView alloc]initWithFrame:CGRectMake(10, y, 93, 75)];
imgLineup.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.0, 0.0);
And then to the following.
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
imgButton.layer.anchorPoint = CGPointMake(0.5, 0.5);
imgButton.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);
}
completion:^(BOOL finished) {
NSLog(#"done");
}];
just try with this. import #import <QuartzCore/QuartzCore.h> then put below code while adding the uimageView into subView of self.view
CABasicAnimation *zoomAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
[zoomAnimation setDuration:0.8];
[zoomAnimation setRepeatCount:1];
[zoomAnimation setFromValue:[NSNumber numberWithFloat:0.1]];
[zoomAnimation setToValue:[NSNumber numberWithFloat:1.0]];
[zoomAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[imageView layer] addAnimation:zoomAnimation forKey:#"zoom"];
What i suggest may be kind of hack but it will be an easier way to achieve what you want:
You set the initial frame of imageView as:
CGRectMake(center, center, 0, 0);
So in your case it will be something closer to :
CGRectMake(46, 37, 0, 0);
Then animate it with new rect of something like this:
CGRectMake(0, 0,93,75);
You can use simple UIViewAnimation for this;
[UIView beginAnimations:#"zoom" context:NULL];
[UIView setAnimationDuration:0.3];
imageView.frame = CGRectMake(0, 0, 93, 75); ;
[UIView commitAnimations];
Hope It works
What you are trying to achieve is a scale transform i.e. animating UIView size from size(0,0) to size(w,h). Same effect can be achieved by CGAffineTransformMakeScale.
Initially when you create the view apply CGAffineTransformMakeScale(0.0,0.0) then animate size scale up to CGAffineTransformMakeScale(1.0,1.0).
Code:
// Create the view and apply correct frame
UIView *tagView = [[UIView alloc] initWithFrame:CGRectMake(50, 100, 100, 100)];
tagView.tag = kTag;
//Apply scale transform, to make size(0,0)
tagView.transform = CGAffineTransformMakeScale(0,0);
[self.view addSubview:tagView];
/// ............
UIView *tagView = [self.view viewWithTag:kTag];
//Now animate the view size scale up
[UIView animateWithDuration:0.5
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
tagView.transform = CGAffineTransformMakeScale(1.0,1.0);
}
completion:NULL
];
This animation will happen about the center point of the view as you want, thus avoiding the need to play with anchorPoint and frame, which can be tricky. Read more about the relation between frame and anchorPoint from this answer.

UIView animateWithDuration interfering with other CGRectMake

I have a CGRectMake that used to jump an image to a different position
image.frane=CGRectMake( x,y,w,h);
Then I wanted to translate and scale a Label (on the same ViewController) to another position
CGPoint newCenter = CGPointMake(x,y);
[UIView animateWithDuration: 1.0
delay: 0
options: 0
animations:^{label.center = newCenter ; label.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.2, 0.2);}
completion:^(BOOL finished) {
label.transform = CGAffineTransformMakeScale(1.0, 1.0);
label.alpha = 0;
}
];
The problem I'm having is when I use the animateWithDuration the image doesn't move but the Label does. If I comment out the animation the image moves again. Am I doing something wrong?
try this bellow code...
[UIView animateWithDuration:1.0f animations:^{
imageView.frame = CGRectMake(newCenter.x, newCenter.y, imageView.frame.size.width, imageView.frame.size.height);
}];
Also you can move UIImageView or anything else with this bellow code... i use this code for scroll the UIScrollView when keyboard appear.. i add the code with your requirement..
UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0f];
imageView.frame = CGRectMake(newCenter.x, newCenter.y, imageView.frame.size.width, imageView.frame.size.height);
[UIView commitAnimations];
i hope this helpful to you...

Layer Position jumps at start of (Core) Animation

So, I'm trying to create a tile flipping effect, like on Windows Phone 7.
So far I have the following code, but I have a couple of queries.
CALayer *layer = self.theRedSquare.layer;
CATransform3D initialTransform = self.theRedSquare.layer.transform;
initialTransform.m34 = 1.0 / -1000;
[UIView beginAnimations:#"Scale" context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
layer.transform = initialTransform;
layer.anchorPoint = CGPointMake(-0.3, 0.5);
CATransform3D rotationAndPerspectiveTransform = self.theRedSquare.layer.transform;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, M_PI , 0 , -self.theRedSquare.bounds.size.height/2, 0);
layer.transform = rotationAndPerspectiveTransform;
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
1. How come my my red square (a simple UI view) translates to the right at the start of the animation?
2. For the anchor point is it possible to set a position on the parent view? At the moment I am arbitrarily setting it relative to the current view.
Thanks in advance for any pointers.
Before animation
During animation (notice the square has shifted right)
After animation (notice the square has shifted right)
Video added: example video
-(void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view
{
CGPoint newPoint = CGPointMake(view.bounds.size.width * anchorPoint.x, view.bounds.size.height * anchorPoint.y);
CGPoint oldPoint = CGPointMake(view.bounds.size.width * view.layer.anchorPoint.x, view.bounds.size.height * view.layer.anchorPoint.y);
newPoint = CGPointApplyAffineTransform(newPoint, view.transform);
oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform);
CGPoint position = view.layer.position;
position.x -= oldPoint.x;
position.x += newPoint.x;
position.y -= oldPoint.y;
position.y += newPoint.y;
view.layer.position = position;
view.layer.anchorPoint = anchorPoint;
}
-(void)animateView:(UIView *)theRedSquare
{
CALayer *layer = theRedSquare.layer;
CATransform3D initialTransform = theRedSquare.layer.transform;
initialTransform.m34 = 1.0 / -1000;
[self setAnchorPoint:CGPointMake(-0.3, 0.5) forView:theRedSquare];
[UIView beginAnimations:#"Scale" context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
layer.transform = initialTransform;
CATransform3D rotationAndPerspectiveTransform = theRedSquare.layer.transform;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, M_PI , 0 , -theRedSquare.bounds.size.height/2, 0);
layer.transform = rotationAndPerspectiveTransform;
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
}
Taken from This, and slightly tweaked.. Hopefully it helps
Changing my CALayer's anchorPoint moves the view
If you make the square its own view, flipping is built-in
[UIView beginAnimations:#"flip" context:nil];
[UIView setAnimationDuration:.35f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft
forView:self.window cache:YES];
// change to the new view (make this one hidden, the other not)
[UIView commitAnimations];
The acceptable range of the anchorPoint of a CALayer is [0,1]. In your case, where you are attempting to flip around the Y axis, your layer's anchor point should be [0, 0.5].

Can you perform/animate 2transforms on a layer at the same time?

[UIView beginAnimations:#"trans" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(moveCardToSide)];
[UIView setAnimationDuration:1.0];
CGRect frame = playersCard.view.layer.frame;
frame.origin.x = -30;
playersCard.view.layer.frame = frame;
playersCard.view.layer.transform = CATransform3DScale(playersCard.view.layer.transform, 0.7, 0.7, 1.0);
playersCard.view.layer.transform = CATransform3DRotate(playersCard.view.layer.transform, 30*M_PI/180, 0.0, 1.0, 0.0);
[UIView commitAnimations];
Both of the above transforms are performed. But only the 2nd once is animated. They both animate if i run them separately. It is possible to combine them into 1 animation?
Whats happening with the scale is that it jumps from 100% size to 70% then animates the rotate.
As you've written it, the transformations are being combined into a single animation. If you want two animations, with the second occurring right after the first simply move your second transform adjustment into an UIView animation block in -moveCardToSide