Ive looked around and couldn't find a simple method. I have an animation that plays when a collision occurs, although the animation can't get past the first frame until the objects are completely separated as the collision detection keeps firing.
Does anyone know how to either force the animation to play all the way through or have the collision detection only check once? (although the collision detection would need to be running again afterwards to repeat the process).
if (CGRectIntersectsRect(Heli.frame, AstroidBig.frame)) {
animation2.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"Image 1"],
[UIImage imageNamed:#"Image 2"],
[UIImage imageNamed:#"Image 3"],
nil];
[animation2 setAnimationRepeatCount:1];
animation2.animationDuration = 0.4;
[animation2 startAnimating];
[self performSelector:#selector(enemyreset) withObject:nil afterDelay:1];
}
The 'enemyreset' is the function that will reset the object back into play from the collision point.
Set a flag in the above method to indicate that you are animating (you will need to add it as a property). Only start the animation if you are not already animating. Then reset the flag in your enemyreset method.
if (CGRectIntersectsRect(Heli.frame, AstroidBig.frame)) {
if (!self.alreadyAnimating) {
animation2.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"Image 1"],
[UIImage imageNamed:#"Image 2"],
[UIImage imageNamed:#"Image 3"],
nil];
[animation2 setAnimationRepeatCount:1];
animation2.animationDuration = 0.4;
[animation2 startAnimating];
[self performSelector:#selector(enemyreset) withObject:nil afterDelay:1];
self.alreadyAnimating = YES;
}
}
Related
I have a animation assigned to the uiimageview with the following code
Fire.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"firework1.png"],
[UIImage imageNamed:#"firework2.png"],
[UIImage imageNamed:#"firework3.png"],
[UIImage imageNamed:#"firework10.png"],nil];
[Fire setAnimationRepeatCount:0];
Fire.animationDuration = 0.5;
[Fire startAnimating];
I want the animation to stop when it reaches 0.5 I tried a if statement but it didn't work. Please help.
According to the UIImageView documentation setting the animation repeat count to 0 will make it repeat indefinitely, try using [Fire setAnimationRepeatCount:1]; instead.
In Xcode I've got 2 buttons: Start and Stop.
When you click Start startClickis called, when you click Stop stopClick is called.
When you click Start a UIImageView image will flash different images from the NSArray. When you click Stop, it stops, but I want it to stop on the image that was showing when I clicked Stop. At the moment it just stops and disapears... Any help?
Heres the part of the code:
- (IBAction)startClick:(id)sender {
color.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed: #"img1.png"],
[UIImage imageNamed: #"img2.png"],
[UIImage imageNamed: #"img3.png"],
[UIImage imageNamed: #"img4.png"],nil];
[color setAnimationRepeatCount: 0];
color.animationDuration = 1;
[color startAnimating];
}
- (IBAction)stopClick:(id)sender {
[color stopAnimating];
//What code do i put here to display the last image? (as i clicked stop).
}
I would also like to add if statments for if the color displayed is img1.png then do this... and if its img2.png do that...
This code will pause your Animation:
color.frame = [[color.layer presentationLayer] frame];
[color.layer removeAllAnimations];
I have two different images, that are essentially just inverses of each other. I would like to animate them back and forth to create a somewhat moving effect. In the AppDelegate didFinishLaunching I have:
myImageWalk = [[UIImageView alloc] initWithFrame:CGRectMake(0,0, 320, 568)];
[self.myImageWalk setImage: [self loadingImage]];
[window addSubview:myImageWalk];
[window bringSubviewToFront:myImageWalk];
Then, also in the App Delegate, I have:
-(UIImage*)loadingImage
{
NSArray *animationFrames = [NSArray arrayWithObjects:
[UIImage imageNamed:#"original.png"],
[UIImage imageNamed:#"second.png"],
[UIImage imageNamed:#"original.png"],
[UIImage imageNamed:#"second.png"],
[UIImage imageNamed:#"original.png"],
[UIImage imageNamed:#"second.png"],
[UIImage imageNamed:#"original.png"],
[UIImage imageNamed:#"second.png"],
[UIImage imageNamed:#"original.png"],
[UIImage imageNamed:#"second.png"],
[UIImage imageNamed:#"original.png"],
[UIImage imageNamed:#"second.png"],
[UIImage imageNamed:#"original.png"],
[UIImage imageNamed:#"second.png"],
[UIImage imageNamed:#"original.png"],
[UIImage imageNamed:#"second.png"],
[UIImage imageNamed:#"original.png"],
[UIImage imageNamed:#"second.png"],
nil];
return [UIImage animatedImageWithImages:animationFrames duration:6.0f];
}
But, nothing happens, no image ever shows up. What am I doing wrong?
Some code below you can try.
Note you don't need to repeat the series of imageNamed:, just set duration as needed for one loop.
myImageWalk = [[UIImageView alloc] initWithFrame:CGRectMake(0,0, 320, 568)];
myImageWalk.image = [self loadingImage];
self.myImageWalk.animationRepeatCount = 0;
[window addSubview:myImageWalk];
[window bringSubviewToFront:myImageWalk];
//when you want the animation to start
[self animateImages];
//then later at some appropriate time:
[self stopAnimatingImages];
- (UIImage*)loadingImage {
NSArray *animationFrames = [NSArray arrayWithObjects:
[UIImage imageNamed:#"original.png"],
[UIImage imageNamed:#"second.png"],
nil];
return [UIImage animatedImageWithImages:animationFrames duration:6.0f];
}
- (void)animateImages {
if (![self.myImageWalk isAnimating]) {
[self.myImageWalk startAnimating];
}
}
- (void)stopAnimatingImages {
if ([self.myImageWalk isAnimating]) {
[self.myImageWalk stopAnimating];
}
}
Note: unless this is a test app or class assignment, you should move this logic from AppDelegate to ViewContoller, as it is best practice to minimize the work done during didFinishLaunching.
I haven't tried it, but maybe try wrapping your code inside this block:
[UIView animateWithDuration:6f animations:^{
[UIImage animatedImageWithImages:animationFrames duration:6.0f]
} completion:^(BOOL finished) {
//Callback after animation was completed
[view removeFromSuperview];
}];
I have successfully created a UIView which plays an animation of images from an NSArray of images. I am trying to get this image to move at the same time the animation is playing. Use of the .center property of UIView just isn't working, and I must have some sort of syntactic error, which I cannot for the life of me figure out.
Original post:
I'm playing with brandontreb's tutorial. I can successfully get the animated sprite to dance in place, but I want it to actually scoot across the screen. Can some dear soul:
Please help me fix what I'm doing wrong to make the center of the UIimage
actually move across screen?
Or even better, update this to
"animation block" best practices?
I will surely study your fixes for hours.
- (IBAction)startWalking:(UIButton *)sender {
NSArray * imageArray = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"1.png"],
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
[UIImage imageNamed:#"4.png"],
[UIImage imageNamed:#"5.png"],
[UIImage imageNamed:#"6.png"],
[UIImage imageNamed:#"7.png"],
[UIImage imageNamed:#"8.png"],
[UIImage imageNamed:#"9.png"],
[UIImage imageNamed:#"10.png"],
[UIImage imageNamed:#"11.png"],
[UIImage imageNamed:#"12.png"],
nil];
UIImageView * ryuJump = [[UIImageView alloc] initWithFrame:
CGRectMake(100, 125, 150, 130)];
ryuJump.animationImages = imageArray;
ryuJump.animationDuration = 1.1;
ryuJump.animationRepeatCount=5;
CGPoint p = ryuJump.center;
p.x += 100;
ryuJump.center = p;
[UIView animateWithDuration:20
delay:0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
ryuJump.center = CGPointMake(p.x, p.y);
}
completion:^(BOOL finished){
}];
ryuJump.contentMode = UIViewContentModeBottomLeft;
[self.view addSubview:ryuJump];
[ryuJump startAnimating];
}
Remove:
ryuJump.center = p;
You're basically telling uiview to animate to the exact same position you just set it to (so nothing will happen).
I am using a UIImageView to display both still and animated images. So sometimes, I'm using .image and sometimes I'm using .animationImages. This is fine.
Whether it's static or animated, I store the UIImages's in item.frames (see below)
The problem is that I'd like to display a UIActivityIndicatorView in the center of the view when the animation frames are loading. I would like this to happen with no images or frames in there. The line that isn't doing what it's supposed to is:
[self.imageView removeFromSuperview];
As a matter of fact, setting it to another image at this point doesn't do anything either. It seems like none of the UI stuff is happening in here. BTW,
NSLog(#"%#", [NSThread isMainThread]?#"IS MAIN":#"IS NOT");
prints IS MAIN.
The image that is in there will stick around until the new animation frames are all in there (1-2 seconds) and they start animating
This is all being run from a subclass of UIView with the UIImageView as a subview.
- (void)loadItem:(StructuresItem *)item{
self.imageView.animationImages = nil;
self.imageView.image = nil;
[self.spinner startAnimating];
self.item = item;
if (item.frameCount.intValue ==1){
self.imageView.image = [item.frames objectAtIndex:0];
self.imageView.animationImages = nil;
}else {
[self.imageView removeFromSuperview];
self.imageView =[[UIImageView alloc] initWithFrame:self.bounds];
[self addSubview:self.imageView ];
if( self.imageView.isAnimating){
[self.imageView stopAnimating];
}
self.imageView.animationImages = item.frames;
self.imageView.animationDuration = self.imageView.animationImages.count/12.0f;
//if the image doesn't loop, freeze it at the end
if (!item.loop){
self.imageView.image = [self.imageView.animationImages lastObject];
self.imageView.animationRepeatCount = 1;
}
[self.imageView startAnimating];
}
[self.spinner stopAnimating];
}
My ignorant assessment is that something isn't being redrawn once that image is set to nil. Would love a hand.
What I have found is not an answer to the question, but rather a much better approach to the problem. Simply, use NSTimer instead of animationImages. It loads much faster, doesn't exhaust memory and is simpler code. yay!
Do this:
-(void)stepFrame{
self.currentFrameIndex = (self.currentFrameIndex + 1) % self.item.frames.count;
self.imageView.image = [self.item.frames objectAtIndex:self.currentFrameIndex];
}
and this
-(void)run{
if (self.item.frameCount.intValue>1){
self.imageView.image = [self.item.frames objectAtIndex:self.currentFrameIndex];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1/24.0f target:self selector:#selector(stepFrame) userInfo:nil repeats:YES];
}else{
self.imageView.image = [self.item.frames objectAtIndex:0];
}
}