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];
}];
Related
I want a transition within my app that is like the mystery revolving wall from old scooby doo cartoons. I want the screen to revolve when switching views. Anyone point me in the right direction for the possibility of accomplishing this?
Or this, which uses far less ink:
UIView *bookCaseView; // this is the container... the haunted wall
UIView *booksView; // just an ordinary set of books, right?
UIView *spookyBackside; // ruh-roh, raggy!
[UIView transitionWithView:containerView
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[booksView removeFromSuperview];
[bookCaseView addSubview:spookyBackside]; }
completion:NULL];
I think this is what you are looking for:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
//optional if you want to do something after the animation
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(myAnimationDidFinish:finished:context:)];
//
[view2 setFrame:CGRectMake(0, 0, view2.frame.size.width, view2.frame.size.height)];
[view1 addSubview:view2];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:view1 cache:YES];
[UIView commitAnimations];
And to flip back:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
//optional if you want to do something after the animation
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(myOtherAnimationDidFinish:finished:context:)];
//
[view2 removeFromSuperview];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view1 cache:YES];
[UIView commitAnimations];
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
I need to flip a card and then flip it back. I have written code to do that with no trouble. The trouble comes because users can flip this card back and forth as many times as they want, and it seems that the effect is cumulative. On the second try, the card spins like a top. I'm not completely surprised, as there only seems to be a way to add animation, not clear one from the view. Is there a way to 're-set' a UIView of any animations I had previously committed? Is there a way to capture it and re-use it without committing a new one? Or am I missing something obvious? This is my code:
if (self.flipped) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
forView:self
cache:YES];
[imageView removeFromSuperview];
[UIView commitAnimations];
self.flipped = NO;
} else {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:self
cache:YES];
[self addSubview:imageView];
[UIView commitAnimations];
self.flipped = YES;
}
Thanks for reading.
To cancel all ongoing animations:
#import <QuartzCore/QuartzCore.h>
...
[view.layer removeAllAnimations];
To start a new animation that kills existing animations, if any, and starts the movement from wherever the view currently is — which I think is what you want:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
... and the rest of it ...
[UIView commitAnimations];
Hopefully one of those will solve your problem.
Whatever your "self" is, put it in a containing view called foo, and then change your setAnimation... line to this:
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:foo
cache:YES];
I'm trying a flip or curl between to views in a container which works pretty well using the following code:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.8];
[UIView setAnimationTransition:animationOption
forView:container cache:YES];
[container addSubview:nuView];
[oldView removeFromSuperview];
[UIView commitAnimations];
but does not with
[UIView transitionWithView:container
duration:.8
options:animationOption
animations:^
{
[container addSubview:nuView];
[oldView removeFromSuperview];
}
completion:^(BOOL finished)
{
}];
Any ideas?
What is animationOption? This code works perfectly well in one of my apps:
[UIView transitionWithView:currentContainerView
duration:0.75
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[currentContainerView.frontView removeFromSuperview];
[currentContainerView addSubview:currentContainerView.flippedSideView];
}
completion:^(BOOL finished) {
// stuff
}];
Check if you are using UIViewAnimationOptionTransition or UIViewAnimationTransition !
I have a working view animation, that curls up a container view, while the containerview.subviews changes. (before the animation a UITableView will be shown, after it is a custom view, name keypadView)
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp
forView:containerView
cache:YES];
[secondView removeFromSuperview];
[containerView addSubview:keypadView];
[UIView commitAnimations];
Now I want to rewrite this code for the iOS4 block-based api, as I want to use the completion block. I wrote this:
[UIView transitionWithView:containerView
duration:.75
options:UIViewAnimationTransitionCurlUp
animations:^{
NSLog(#"Hey Ho");
[secondView removeFromSuperview];
[containerView addSubview:keypadView];
}
completion:NULL];
The views switch — but not animated.
what is wrong with my code?
Edit
completion: ^(BOOL completed){
NSLog(#"completed %d", completed);
}
doesn't help, as NULL is an accepted value, according to the docs
do:
options:UIViewAnimationOptionTransitionCurlUp
instead of:
options:UIViewAnimationTransitionCurlUp
That is why your code works now :).
The sample in the UIView class reference may be wrong - or maybe there's a bug with adding and removing views in the animations block object, but the only way I've been able to get it to work is as follows:
[secondView removeFromSuperview];
[containerView addSubview:keypadView];
[UIView transitionWithView:containerView
duration:.75
options:UIViewAnimationOptionTransitionCurlUp
animations:^{}
completion:^(BOOL finished) {
NSLog(#"finished %d", finished);
}];
Did you leave [UIView beginAnimations:nil context:nil]; above your new block?
Is the completion block always NULL? Try putting an NSLog statement in there or something. I don't know if NULL blocks would mess it up.