How to stop executing FOR loop until code is completed - objective-c

I made this thing. It has no purpose other than for demonstration to myself. Essentially, I'm moving a view that I created around the screen in a loop. The problem is that it doesn't wait until it's done with one animation before starting the other, and so the view bypasses the first two and ends up at the last toastRect after the for loop is done, and it doesn't keep moving after that. How can I force the code to complete each animation before moving on to the next?
int i;
for (i=0; i < 100; i++) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:9];
toast.view.frame = toastRect1;
[UIView commitAnimations];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:9];
toast.view.frame = toastRect2;
[UIView commitAnimations];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:9];
toast.view.frame = toastRect;
[UIView commitAnimations];
NSLog(#"%d",i);
}
}

I think you need to use + (void)setAnimationDidStopSelector:(SEL)selector. Take a closer look at http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html if you want.

You can use the setAnimationDidStopSelector method to chain the animations. Check the docs for details: http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html%23//apple_ref/occ/clm/UIView/setAnimationDidStopSelector:

Related

How to flip two views Objective C iOS 13

I have two views that flip (like Turing over a card horizontally). iOS 13 has depreciated the begin animations code and I'm trying to figure out how to use [UIView animateWithDuration:delay:options:animations:completion:]
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:self.ABCard cache:YES];
[self.ABCard exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
I'm trying to do the following but the animation just switches views instantly with no flip action.
[UIView animateWithDuration:1.0 delay:1.0
options: UIViewAnimationCurveEaseInOut | UIViewAnimationTransitionFlipFromLeft
animations:^{
[self.ABCard exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
} completion:^(BOOL finished){
}];
exchangeSubviewAtIndex doesn't change the look of the animation so it's won't result in an animation, which is why you just see it flip.
Results from this answer may help you with a proper solution: iPhone Flip Animation using UIViewAnimationTransitionFlipFromLeft in landscape mode

UIView beginAnimations fails on selector

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelay:4];
[UIView setAnimationDuration:5];
navigation.frame = CGRectOffset(navigation.frame, 0, 430);
[UIView commitAnimations];
Code block above works fine when called manually on viewDidLoad function or with button tap. But when i try to call that block within a selector function like below, animation doesnt effect. Object jumps to position. What would cause to that?
if ([delegate respondsToSelector:#selector(carouselDidEndScrollingAnimation:)])
{
[delegate carouselDidEndScrollingAnimation:self];
}
- (void) carouselDidEndScrollingAnimation:(iCarousel *)carousel{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:5];
navigation.frame = CGRectOffset(navigation.frame, 0, 430);
[UIView commitAnimations];
}
icarousel github
Still don't know the real problem but
[self performSelector:#selector(makeAnim) withObject:nil afterDelay:0.0001];
solved my problem.
Hope helps anyone.
Still needs a better solution.

animation alpha change

I've always worked with Flash, and it's pretty easy to change the alpha values between one frame and another. Is there a way to do this in xcode 4? I'm animating a logo and I need the first png to disappear while the second one starts appearing. tnx!
Alternatively to esqew's method (which is available prior to iOS 4, so you should probably use it instead if you don't plan to limit your work to just iOS 4), there is also [UIView animateWithDuration:animations:], which allows you to do the animation in a block. For example:
[UIView animateWithDuration:3.0 animations:^(void) {
image1.alpha = 0;
image2.alpha = 1;
}];
Fairly simple, but again, this is available only on iOS 4, so keep that in mind.
Other solution, fade in and fade out:
//Disappear
[UIView animateWithDuration:1.0 animations:^(void) {
SplashImage.alpha = 1;
SplashImage.alpha = 0;
}
completion:^(BOOL finished){
//Appear
[UIView animateWithDuration:1.0 animations:^(void) {
[SplashImage setImage:[UIImage imageNamed:sImageName]];
SplashImage.alpha = 0;
SplashImage.alpha = 1;
}];
}];
This is pretty simple actually. Place the following code where you want the animation to occur:
[UIView beginAnimations:NULL context:NULL];
[UIView setAnimationDuration:3.0]; // you can set this to whatever you like
/* put animations to be executed here, for example: */
[image1 setAlpha:0];
[image2 setAlpha:1];
/* end animations to be executed */
[UIView commitAnimations]; // execute the animations listed above
You can read more about these methods in this document.
If you wanna work with a structure you referred to in your comment on this question:
[UIView beginAnimations:NULL context:NULL];
[UIView setAnimationDuration:3.0]; // you can set this to whatever you like
/* put animations to be executed here, for example: */
[[introAnimation objectAtIndex:0] setAlpha:0];
[[introAnimation objectAtIndex:1] setAlpha:1];
/* end animations to be executed */
[UIView commitAnimations]; // execute the animations listed above
... should work.

How to let two animations for UIView executed one by one

I have a small UIView and want to let it move to center of screen first, and then, zoom to full screen.
But when I begin start an animation like
[UIView beginAnimations:#"animation1" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(showDetailToFullscreen)];
self.currentDetailVC.frame = centerFrame;
[UIView commitAnimations];
And in the same controller, I have a method:showDetailToFullscreen
- (void)showDetailToFullscreen {
CGRect screenFrame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
[UIView beginAnimations:#"animation2" context:nil];
[UIView setAnimationDuration:0.5];
self.currentDetailVC.view.frame = screenFrame;
[UIView commitAnimations];
}
but when start, it still executed together.
I think the problem they are still in the same transaction. But how can I let these two animation executed one by one? Appreciate for any answer!
Try this instead of the setAnimationDidStopSelector:
[self performSelector:#selector(showDetailToFullscreen) withObject:nil afterDelay:0.5];
It's now considered much better to annimate views using the 'blocks' methods that can be found in the "Animating Views with Blocks" section in the UIView Class Reference.
In most of these methods you can specify a "completion" block of code that can be used to start off a second animation when the first animation completes. You could also call showDetailToFullscreen within this completion block.
I'd reccommend trying this method instead.
Are you targetting iOS 4 or later? If so, I recommend using the block-based animation methods instead. What you want to do is very easy:
Example from UIView docs:
[UIView animateWithDuration:0.2
animations:^{view.alpha = 0.0;}
completion:^(BOOL finished){ [view removeFromSuperview]; }];

Cocoa Touch - Slow Moving CGPointMake

I'm using the following code to move an UIImageView across screen. With this code it rockets across the screen but I want it to slowly move. What do I need to do?
[UIView beginAnimations:#"slide-up" context:NULL];
astroid_1.center = CGPointMake(astroidPosX,astroidPosY); // change this to somewhere else you want.
[UIView commitAnimations];
Thanks!
You need to set the duration of the animation:
[UIView setAnimationDuration:1.0];