Why does the view disappear after an animation? - ios

I've been trying to animate an image using this code.
- (void)viewDidLoad
{
dice.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"image1.png"],
[UIImage imageNamed:#"image2.png"],
[UIImage imageNamed:#"image3.png"], nil];
[dice setAnimationRepeatCount:3];
dice.animationDuration = 1;
[super viewDidLoad];
// Do any additional setup after loading the view.
}
Then I have a button that makes the animation play.
-(IBAction) animate:(id)sender {
[dice startAnimating];
}
Everything works perfectly. The animation plays 3 times with duration of 1 second each time. However after the animation has played 3 times, the dice image view simply disappears from the screen. How do I stop this from happening so the image doesn't disappear and I can do other stuff to the image view?

Are you setting dice.image anywhere? The animations are different than the image the imageView contains, and "play in front of" the image and then are removed. I recommend using UIImageView's startAnimatingWithCompletionBlock method:
- (void) viewDidload {
dice.image = [UIImage imageNamed:#"image3.png"]; // big assumption on my part
// the assumption is that this is the image you want
// after animating
dice.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"image1.png"],
[UIImage imageNamed:#"image2.png"],
[UIImage imageNamed:#"image3.png"], nil];
[dice setAnimationRepeatCount:3];
dice.animationDuration = 1
[super viewDidLoad];
}
A "block" is a chunk of one or more lines of code that wait until after the animation finishes to be executed. If you set the image beforehand it will appear "behind" the animations as they run and may not be what you want.

Related

UIImageView animationRepeatCount strange behaviour

So i have this code that animates a set of images an unlimited amount of times just fine, however as soon as i try to limit the number of times it animates it simply does not work. No image is even displayed.
Code that works:
animatedMap.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"0.gif"],
[UIImage imageNamed:#"1.gif"],
[UIImage imageNamed:#"2.gif"],
[UIImage imageNamed:#"3.gif"],
//etc...];
animatedMap.animationDuration = 20.0f;
animatedMap.animationRepeatCount = 0;
[animatedMap startAnimating];
Code that doesn't work:
animatedMap.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"0.gif"],
[UIImage imageNamed:#"1.gif"],
[UIImage imageNamed:#"2.gif"],
[UIImage imageNamed:#"3.gif"],
//etc...];
animatedMap.animationDuration = 20.0f;
animatedMap.animationRepeatCount = 1;
[animatedMap startAnimating];
This just seems like really strange behaviour?
I noticed the same behavior, my solution was to put the start of animation code in a different place.
For me, it was a View Controller, so I put imageView.startAnimating() in viewWillAppear: instead of viewDidLoad:.
I don't 100% understand what is the problem, but one can assume that the animation doesn't fire because by setting the animationRepeatCount to 1, your "one animation" happens before the view is displayed. To be more technical, the CATransaction::Commit with the one animation gets performed before the view is displayed, and not when the view is displayed.
animationRepeatCount is used for cycle all the images in given animationDuration duration.
So if you provide animatedMap.animationRepeatCount = 1; that means only 1 cycle will be run and then the default set image will be displayed. If you didn't define default image to UIImageView then it will be blank(i.e. background color of UIImageView )
There is possibility to have more images then the given time duration for animation, which leads to super-fast animation.
Update 1
You can set last image just before starting your animation.
NSArray *imgArray = [NSArray arrayWithObjects:
[UIImage imageNamed:#"0.gif"],
[UIImage imageNamed:#"1.gif"],
[UIImage imageNamed:#"2.gif"],
[UIImage imageNamed:#"3.gif"],
//etc...];
[animatedMap setImage:[UIImage imageNamed:[imgArray lastObject]]];
animatedMap.animationImages = imgArray
animatedMap.animationDuration = 20.0f;
animatedMap.animationRepeatCount = 0;
[animatedMap startAnimating];

What is the best way to animate images to my apporach?

I have used
image.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"image1"],
[UIImage imageNamed:#"image2"],
[UIImage imageNamed:#"image3"],
[UIImage imageNamed:#"image4"], nil];
[image setAnimationRepeatCount:1];
image.animationDuration = 1;
[image startAnimating];
but it gives a flip book effect to the animation. What I am looking for is a smooth animation to set each image at given time. I have currently is NSTimers to trigger a method then I have code within the method to set a image and another NSTimer to set another image which is in a method so fourth. It gives the animation I am looking for but the problem I am facing is that I am developing a game and I want when the user pauses the game it stops on the current image it is on. The game runs on a NSTimer which triggers a method. All I do to pause the game is to invalidate the NSTimer.
What approach should I take?

How can I make an animation correlate to the current position of a UIImageView?

I have an ImageView that changes between 2 different images. When an event happens and it's in ImageView1, I want it to play a specific animation. And when an event happens and it's in ImageView2, I want it to play a specific, different animation. My code set up so far is essentially
if (ImageView1 == YES)
{
ImageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"ImageAnimate1.png"],
[UIImage imageNamed:#"ImageAnimate2.png"],
[UIImage imageNamed:#"ImageAnimate3.png"],
[UIImage imageNamed:#"ImageAnimate4.png"], nil];
[ImageView setAnimationRepeatCount:1];
ImageView.animationDuration = 1;
[ImageView startAnimating];
}
else
{
ImageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"ImageAnimate5.png"],
[UIImage imageNamed:#"ImageAnimate6.png"],
[UIImage imageNamed:#"ImageAnimate7.png"],
[UIImage imageNamed:#"ImageAnimate8.png"], nil];
[ImageView setAnimationRepeatCount:1];
ImageView.animationDuration = 1;
[ImageView startAnimating];
}
I'm aware it doesn't need to have 2 different sets of animation repeats and duration, but that was just the beginning in the event they change later.
The main problem is, the first set of animations only plays if i'm currently setting it to ImageView1. What I mean is, If i'm tapping/ touching the screen to the left it creates ImageView1, and if i'm tapping to the right it creates ImageView2. How can I change it from having to currently be tapping to the left to play that animation, to just playing the animation when the ImageView is currently displayed as such?
It might be as simple as setting it to the current UIImage, but i'm not exactly sure how to do it.
In other words, I would want to somehow write.
if (UIImage ImageViewLeft = YES)
ImageView.animationImages etc etc etc.
else ImageView.animationImages would be the second variation.
EDIT: I just changed it to
if (ImageView.image == [UIImage imageNamed:#"ImageLeft.png"])
{ code here
What happens is though now i cant change direction until another event happens. Essentially it will be stuck in either left or right until the event happens and then it correlates to the correct image then. .
A simple way would be to create a BOOL for imageIsRight. You set it to YES when you start playing an animation on the right, you set it to NO, when it goes left. Then create a timer which fires every .05 seconds (or whatever works). That timer can call a method which checks the BOOL you created and either repeats/continues the current animation or stops it and starts the other.
The above details may not be perfect for your scenario, which is a bit fuzzy to me, but the approach should get you where you need to be.

UIImageView Animation Images, find out which image is showing

I have UIImageView which display images via animation. Please see code below
NSArray *images = [NSArray arrayWithObjects:[UIImage imageNamed:#"Banner1.png"],[UIImage imageNamed:#"Banner2.png"],[UIImage imageNamed:#"Banner3.png"], nil];
BannerImageView.animationImages = images;
BannerImageView.animationDuration = 9;
[BannerImageView startAnimating];
Now I would like to know which image is on display when I touch on UIImageView(or transparent button which add on top of UIImageView)
- (IBAction)BannerPressed:(id)sender {
[BannerImageView stopAnimating];
NSLog(#"How would i know what image currently showing on BannerView");}
Please help me to find answer!

iOS adding subviews to a scroll view

I'm using a double for loop to add UIButtons to a UIScrollView in a grid format. These UIButtons take time to load as they have subviews that are UIImageViews which get their UIImages by downloading data off the internet.
Right now, the subviews don't show until AFTER the method completely finishes executing. Correct me if I'm wrong, but I'm guessing xcode doesn't show added subviews until a method is done executing.
However, I do want to show each subview getting added one at a time, as a cool loading effect. How would I implement this?
Thanks!
You should use multiple threads to load your pictures so that your main thread does not become sluggish. I recently wrote something similar...Take a look at my code from my viewWillAppear method:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
self.myImages = [self.myModel retrieveAttachments]; //Suppose this takes a long time
for (UIImage *image in self.myImages)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self addImageToScrollView:image animated:YES]; });
}
}
});
The addImageToScrollView method would be like so:
-(void) addImageToScrollView: (UIImage *) image animated: (BOOL) animated
{
//Create image view
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.image = image;
if(animated)
{
imageView.alpha = 0;
[self.myScrollView addSubview:imageView];
[UIView animateWithDuration:ADD_IMAGE_APPEARING_ANIMATION_SPEED animations:^{
imageView.alpha = 1;
}];
}
else
{
[self.myScrollView addSubview:imageView];
}
}

Resources