Remove a subview with ainimation - iphone

I am trying to remove a subview form a view with animation like below. However, when I click a button to run the code, the view is removed immediately. Does anyone know what happen here.
Thanks,
CGRect rect=[self.view viewWithTag:10].frame;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationDidStopSelector:#selector(removeLayer)];
[[self.view viewWithTag:10] setFrame:CGRectMake(rect.origin.x, btn.frame.origin.y, rect.size.width, 0)];
[UIView animateWithDuration:1.0 animations:^{[[self.view viewWithTag:10] setFrame:CGRectMake(rect.origin.x, btn.frame.origin.y, rect.size.width, 0)];} completion:^(BOOL finished){[[self.view viewWithTag:10] removeFromSuperview];}];
[UIView commitAnimations];
-(void)removeLayer{
[[self.view viewWithTag:10] removeFromSuperview];
}

It looks like you are trying to use two different animation methods simultaneously. All you need is:
CGRect rect=[self.view viewWithTag:10].frame;
[UIView animateWithDuration:1.0 animations:^{[[self.view viewWithTag:10] setFrame:CGRectMake(rect.origin.x, btn.frame.origin.y, rect.size.width, 0)];} completion:^(BOOL finished){[[self.view viewWithTag:10] removeFromSuperview];}];

You are combining both types of animation API - I think the block-based one is returning immediately so your didStopSelector is being called straight away.
Try just using this part of it:
[UIView animateWithDuration:1.0 animations:^{[[self.view viewWithTag:10] setFrame:CGRectMake(rect.origin.x, btn.frame.origin.y, rect.size.width, 0)];} completion:^(BOOL finished){[[self.view viewWithTag:10] removeFromSuperview];}];

I think that you forgot to set animation delegate:
[UIView setAnimationDelegate:self];
In your code UIView doesn't know to which object it should send "removeLayer" selector

Related

Not able to remove image from superview

I've created an animation that, when finished, is supposed to remove the image being animated. For some reason, it's not being working (i.e. it's not removing the image). Is there something I'm doing wrong?:
[UIView animateWithDuration:1.8 delay:0 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
appleView[i].frame = CGRectMake(applePosition, 400.0, 25.0, 25.0);
}
completion:^(BOOL finished){ [appleView[i] removeFromSuperview]; }];
The possible reason is that appleView[i] is nil. Put a breakpoint inside completion block and check that.
try with this code ..
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.8];
[UIView setAnimationTransition: UIViewAnimationOptionCurveEaseInOut forView:self.view cache:YES];
[appleView[i] removeFromSuperview];
[UIView commitAnimations];
i hope this help you...
Is appleView a local variable, or a class member? Does anything else alter appleView?
The completion block will run around 1.8 seconds after you start the animation, if appleView is a class member and something changes it you could be removing the wrong thing. Try capturing appleView[i] in a local variable, like this:
UIView *goingAway = appleView[i];
[UIView animateWithDuration:1.8 delay:0 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
goingAway.frame = CGRectMake(applePosition, 400.0, 25.0, 25.0);
} completion:^(BOOL finished){
[goingAway removeFromSuperview];
}];

iPhone:Animation move view controller upward

I am developing an iPhone application, where i need to move a first view controller slowly upward in animation and move to second view controller. I am thinking to use CoreAnimation for moving the first view controller slowly upward and push to next view controller. Could someone help on giving what are the classes/apis available to achieve this?
Thank you!
Try this,
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:yourfirstview cache:YES];
[UIView setAnimationDidStopSelector:#selector(remove_view)];
//change frame here
yourfirstview.frame =CGRectMake(0,-480,320,480);
[UIView commitAnimations];
-(void)remove_view
{
[yourfirstview removeFromSuperview];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:yoursecondview cache:YES];
//change frame here
yoursecondview.frame =CGRectMake(0,0,320,480);
[UIView commitAnimations];
}
You can easily achieve this on a single view controller using multiple UIViews
As per Apple's documentation:
In iOS 4 and later, use the block-based animation methods.
So, in order to produce the intended results, using the following code.
UIView *mySecondView = [[UIView alloc] initWithFrame:CGRectMake(0, 480, 320, 480)];
[mySecondView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:mySecondView];
[UIView animateWithDuration:2.0 delay:3.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[mySecondView setTransform:CGAffineTransformMakeTranslation(0, -480)];
}completion:^(BOOL done){
}];

How to get animation end notification

I want to do some action once animation ended.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.80f];
self.view.transform =
CGAffineTransformMakeTranslation(
self.view.frame.origin.x,
480.0f + (self.view.frame.size.height/2) // move the whole view offscreen
);
[self.view setAlpha:0];
[UIView commitAnimations];
I have done animation like above, How to find out animation ended, so that I can do my action after that.
Use this:
[UIView animateWithDuration:0.80f animations:^{
self.view.transform =
CGAffineTransformMakeTranslation(
self.view.frame.origin.x,
480.0f + (self.view.frame.size.height/2) // move the whole view offscreen
);
[self.view setAlpha:0];
}
completion:^(BOOL finished){
// your code
}];
Add this to your animation:
[UIView setAnimationDidStopSelector:#selector(myAnimationEnded)];
[UIView setAnimationDelegate:self];
and this method will tell you when it stops;
- (void)myAnimationEnded{
NSLog(#"animation ended");
}
Use the UIView's -animateWithDuration:animations:completion: class method.
[UIView animateWithDuration:0.8 animations:^{
CGAffineTransformMakeTranslation(
self.view.frame.origin.x,
480.0f + (self.view.frame.size.height/2) // move the whole view offscreen
);
[self.view setAlpha:0];
} completion:^(BOOL finished) {
//this block is called when the animation is over
}];
Write your code after [UIView commitAnimations];. The animation remains between the beginAnimations and the commitAnimations.
Not that setAnimationDelegate
Use of this method is discouraged in iOS 4.0 and later. If you are using the block-based animation methods, you can include your delegate’s start and end code directly inside your block.

UIView Animation on multiple UIImageViews in ARC

I have an animation in my app that grows a UIImageView and then shrinks it (really two animations). Throughout the app this may happen on several different UIImageViews. I found a way to do this that worked really well, but it now doesn't seem to be compatible with Automatic Reference Counting. Here is my code:
[UIView beginAnimations:#"growImage" context:imageName];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDelegate:self];
imageName.transform = CGAffineTransformMakeScale(1.2, 1.2);
[UIView commitAnimations];
and then:
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(UIImageView *)context {
if (animationID == #"growImage") {
[UIView beginAnimations:#"shrinkImage" context:context];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDelegate:self];
context.transform = CGAffineTransformMakeScale(0.01, 0.01);
[UIView commitAnimations];
}
}
This worked perfectly and I was very happy with it, until I tried converting my project to ARC. I now get the error "Implicit conversion of an Objective-C pointer to 'void *' is disallowed with ARC" on these lines in which I try to pass a UIImageView as the context for the animation:
[UIView beginAnimations:#"growImage" context:imageName];
[UIView beginAnimations:#"shrinkImage" context:context];
Does anybody know of another way that I can alert the "animationDidStop" function of which UIImageView I want it to act on that would be compliant with ARC?
Thanks so much in advance!
Any reason you are not using the much simpler block based animation?
[UIView animateWithDuration:0.5 animation:^{
imageName.transform = CGAffineTransformMakeScale(1.2, 1.2);
} completion ^(BOOL finished) {
[UIView animateWithDuration:0.5 animation:^{
imageName.transform = CGAffineTransformMakeScale(0.01, 0.01);
}];
}];
You can do as follows:
[UIView beginAnimations:#"growImage"
context:(__bridge void*)imageName];
imageName.transform = ...
[UIView commitAnimations];

Scaling a UIView during transitionFromView?

I'm using a container UIView to replicate the kind of behavior the iTunes store does when you tap on album artwork and it flips and scales.
Current code looks like:
//mainView is 300x300x, smallView is 30x30
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0];
[UIView transitionFromView:mainView toView:smallView duration:3.0 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
containerView.frame = CGRectMake(275, 415, 30, 30);
[UIView commitAnimations];
I can't seem to get the content of the containerView to scale during the animation, the frame just closes in on the content. I tried applying some transforms to both the view and the layers and a bunch of other things but I can't seem to get it to behave properly.
Rather than setting the frame, try using a transform instead:
- (void)setStartTransform:(CGAffineTransform)transform;
- (void)setEndTransform:(CGAffineTransform)transform;
Something like
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0];
[UIView transitionFromView:mainView toView:smallView duration:3.0 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
//containerView.frame = CGRectMake(275, 415, 30, 30);
[containerView setStartTransform: CGAffineTransformIdentity];
[containerView setEndTransform: CGAffineTransformMakeScale(0.1, 0.1)];
[UIView commitAnimations];
(You might need to apply a translate to the transform too.)
Try it this way:
[UIView transitionWithView:mainView
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
containerView.frame = CGRectMake(275, 415, 30, 30)
}
completion:NULL];