UIView beginAnimations with subviews - iphone

I have a nice and easy "zoom" animation for a view, which starts as a dot and animates up to full screen size:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
myView.frame = CGRectMake(0,0,320,480);
myView.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
So far so good :-)
The problem is that when I add subviews to myView, to my surprise, they do not follow their superview's animation scheme!?!?
Btw. subviews are currently added as usual in MyView's initWithFrame. I tried to set their transform property to CGAffineTransformIdentity bu it did not help.
So, what needs to be done to allow a subview of myView to also animate in a nice "zoom" fashion together with its superview?
Thanks in advance!
/John

I just ran in to the same problem, and the solution was surprisingly easy. Whereas modifying the frame size only affects the current view, not the subviews (as you noticed), the transform property applies to the subviews as well.
I'm trying to do the reverse of what you're doing (have a subview that appears to 'drop' on to the top of an existing view when displayed, rather than zoom from the center). This code works for me:
self.transform = CGAffineTransformMakeScale(2,2);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
self.transform = CGAffineTransformMakeScale(1,1);
self.alpha = 1.0;
[UIView commitAnimations];
Try setting self.transform to CGAffineTransformMakeScale(0,0) before beginning the animation, and set it back to (1,1) before committing. Don't modify the frame at all - leave it at the size you want the view to have after the animation completes.

You can always use the auto-sizing in the interface builder . This way you can specify the left/margin which you don't want to change and the axis along which you want the particular sub-view to resize to .

Related

How to add a subview with drag in animation from top of the view, in iOS?

I need to add a UIDatePicker subview on a button click to my main view.
How can I add the view with animation such that the subview flips in from the top of the main view and on removing ,undergoes the reverse animation ? I know the subview can be added in a frame that is outside the visible area of the view and then moving it to visible area using CABasicAnimation will be abetter choice. So need help regarding the animation block that I should use.
Thanks in advance
Try this bellow code... here if yourView default frame with origin y = -500 then try bellow code on any UIButton click event.. also set frame which you want
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
CGRect frame = yourView.frame;
frame.origin.y = frame.origin.y + 500; // give any value for display yourView
yourView.frame = frame;
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:yourView cache:YES];
[UIView commitAnimations];
Use CATransaction for animation.

uiview CGAffineTransform animates backwards

I have a UIView subclass which I am able to successfully use UIView animations on.
This UIView also has subviews, which I also want to be able to UIView animate.
However, it seems that whenever I create an animation and apply it to the parent view it works fine, but if I apply the animation to the child view it animates backwards.
For example, if I scale my UIView parent(self) by a factor of 2 (to double the width and height):
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration:2];
[UIView setAnimationDelay:2];
CGAffineTransform scaleTransform = CGAffineTransformScale( self.transform, 2, 2 );
self.transform = scaleTransform;
[UIView commitAnimations];
then this works fine.
But if I do the same on the child:
UIView *myObj = [[self subviews] objectAtIndex:0];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration:2];
[UIView setAnimationDelay:2];
CGAffineTransform scaleTransform = CGAffineTransformScale( myObj.transform, 2, 2 );
myObj.transform = scaleTransform;
[UIView commitAnimations];
It doesn't work. What happens visually is that the child view immediately shrinks down and then after the delay scales back up to it's original size.
If I log the transform parameters it looks the same for both parent and child and I have tried setting CGAffineTransformIdentity.
Any ideas what might be the problem?
I was overriding layoutSubviews and in there I was assigning sizes/positions of the views based upon device orientation which was conflicting.doh!

How to animate a NIB so that it enters the screen from the right side

I guess this is quite basic, but I was wondering if there is an easy way to animate an entire NIB onto the screen... coming from the right. Ideally, I'd like it to bounce a bit once it stops (i.e. if the NIB is supposed to scroll to position X = 0, I'd like to go it slightly negative before coming back to 0).
This is what I have so far:
[UIView animateWithDuration:0.5
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
TabsEdit *tEdit = [[TabsEdit alloc] initWithNibName:#"TabsEdit" bundle:nil];
self.tabsEdit = tEdit;
[self.view addSubview:tEdit.view];
[tEdit release];
}
completion:^(BOOL finished){
}
Is there any easy solution or will I need to animate every single element in the NIB into view and then add my little bounce effect to it?
I'd be grateful for any suggestions of how to achieve this efficiently.
To get more complicated animations (if you want to have more segments to the bouce), you should go down to the CoreAnimation layer and define keyframes. Else have a series of embedded animateWithDuration/Completions, with each one doing a different part of the bounce). If all elements of a view are subviews, then when the view is animated, its subviews will follow.
one move repeat to bounce.
[UIView beginAnimations:#"move" context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.25];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
if(movingIn){
view.frame = CGRectMake(0.0f, view.frame.origin.x, .view.frame.size.width, view.frame.size.height);
}else{
view.frame = CGRectMake(320.0f, view.frame.origin.x, .view.frame.size.width, view.frame.size.height);
}
[UIView commitAnimations];

UIView Animation, Transforming layer.shadowPath

I created a UIImageView that has a custom shadowPath. This view will be moved left and right across the screen, but I need the shadowPath to have a different transformation than the image layer itself. Is this possible? Moving the image itself works, and the shadow moves as well when I do the following:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
im.center = location;
[UIView commitAnimations];
But if I try to add a layer transformation before "commitAnimations", the shadow will simply take on that property right away, for example:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
im.center = location;
im.layer.shadowPath = [self createPerspectiveShadow:im]; //this will not animate
[UIView commitAnimations];
So, my question is, is there a way to recalculate a shadow during the animation?
Thanks
The UIView animations don’t always allow you to animate CALayer attributes; try using a CABasicAnimation instead.
You can pass a CGPathREf to the toValue
theAnimation.toValue = (id)[UIBezierPath bezierPathWithRect:newRect].CGPath;
see this post

how to implement an iPhone view transition animation with both flipping and scaling?

how can I implement the animation we see in the iPhone Music app's coverflow screen? when you click on a small view, it flips and scales up to another view? how can I do this? I can use core animation to flip and scale a view, but how can I do the transition to another view? thanks
You need an UIView as Container for the two UIViews (frontside/backside) and then remove/add these from/to the container as subviews while doing the animations in between:
UIView *flipContainer;
UIView *frontSide;
UIView *backSide;
//...
-(void)turnUp
{
[backSide removeFromSuperview];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:flipContainer cache:YES];
[UIView setAnimationDuration:1.0];
CGAffineTransform transform = CGAffineTransformMakeScale(1.2, 1.2);
flipContainer.transform = transform;
[UIView commitAnimations];
[flipContainer addSubview:frontSide];
}
-(void)turnDown
{
[frontSide removeFromSuperview];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:flipContainer cache:YES];
[UIView setAnimationDuration:1.0];
CGAffineTransform transform = CGAffineTransformMakeScale(1, 1);
flipContainer.transform = transform;
[UIView commitAnimations];
[flipContainer addSubview:backSide];
}
I'm trying the exact code you are doing - I get a zoom effect but no turn over. The only difference is that right before the turnUp code I add the flipContainer (with back showing) so then it can be flipped over.
// construct animation container
self.flipContainer = [[FlipContainer alloc] init];
[self.flipContainer.view setFrame:CGRectMake(clickedSquareX, clickedSquareY, 200, 200)];
[self.flipContainer.view addSubview:self.backside.view];
// add animation container
[self.myParentView.view addSubview:self.flipContainer.view];
// PROCEED to your turnUp code
The reason I'm doing this is I have a bunch of images in a horizontal UIScrollView and so to 'simulate' a 200x200 image flipping over and zooming to show detail I add my flipContainer with the backside showing the exact image over the exact spot of the pressed image. It should work shouldn't it? A bit confusing to me is the first line of your turnUp code you do:
[backSide removeFromSuperview];
..which would remove the view I just added.
I'm not sure if this is the right spot to put this question in - sorry if it isn't!