views:

300

answers:

4

I'm developing an app that would display images and change them according to the user's action. I've created a subclass of UIView to contain an image, an index number and an array of image names. The code is like this:

@interface CustomPic : UIView {
    UIImageView *pic;
    NSInteger index;
    NSMutableArray *picNames;  //<-- an array of NSString
}

And in the implementation part, it has a method to change the image using a dissolve effect.

- (void)nextPic {
    index++;
    if (index >= [picNames count]) {
    index = 0;
    }
    UIImageView *temp = pic;
    pic.image = [UIImage imageNamed:[picNames objectAtIndex:index]];
    temp.alpha = 0;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    [UIView setAnimationDuration:0.25];
    pic.alpha = 0;
    temp.alpha = 1;
    [UIView commitAnimations];
}

In the viewController, there are several CustomPic which would change the images depends on users' choice. The images would change as expected with the fade in/out effect, but the animation performance is really bad. I've tested it on an iPhone 3G, the Instruments shows that the animation is only 2-3FPS! I tried many methods to simplify and modify the codes but with no hope. Is there something wrong in my code or in my concept? Thanks for any help.

P.S. all the images are 320*480 PNGs with a max size of 15KB.

+1  A: 

Are you running iPhone OS 4 beta? I find the beta OS much slower on the older generation devices like iphone 3g

Mugunth Kumar
I'm running OS 3.1.3, not OS 4.
Anthony Chan
+1  A: 

In that code snippet you are only using one UIImageView:

UIImageView *temp = pic;

So this line does nothing:

pic.alpha = 0;

To fade one image in and another image out, you need two instances of UIImageView.

To speed things up, you might want to load the next image ahead of time. Set a delegate for the animation, and when it completes load the image that will be displayed in the next call of nextPic.

Edit:

If the images are not transparent, try setting the pic.opaque = YES; so the view can ignore underlying views. If that is not an option, try having as few views as possible between the fading view and a full screen opaque view. At each step of the fade, the view must be composited with every underlying view until an opaque view is found.

If you have many transparent views under the fade, consider making a temporary composite of them all, the equivalent of flatten layers in photoshop, and placing the composite as an image in a full screen opaque view before starting the fade. It may delay starting the fade a moment, but the fade itself should be smoother.

drawnonward
I learned that code from another project on the web. I'm not quite sure how that works but it really works in my case (one fade in, one fade out).I have also previously thought of creating one more instance of UIImageView as well. But I was afraid that will increase the memory usage which would eventually trigger the low memory warning. Am I worrying too much? Anyway, I'll test that later. Thanks.
Anthony Chan
Thanks drawnonward!! You are absolutely right! I have a dozen of views and all of them have to be transparent. Making a temp composite of them saved my days! Thanks for your great help! Really appreciate it!
Anthony Chan
A: 

With an animation duration of .25 of a second, you can be guaranteed to get < 4 FPS. What FPS are you targeting?

Kenny
I'm not sure what FPS would be good. But the animation I get is totally not smooth and choppy. What I want is simply a smooth fade in/ fade out effect. Thanks for help anyway~
Anthony Chan
+1  A: 

Try change

[UIView setAnimationDuration:0.25];

to

[UIView setAnimationDuration:0.025];

and see if that's something you are looking for...

ohho
In the simulator, it works fine as what I expected. But on the phone, the animation is extremely unsmooth and choppy. So I think changing the duration is not what I'm looking for. But anyway, thanks for your help~
Anthony Chan
does the 2nd or later rounds of animation also slow? say, if you have 5 images, does the speed increase when you call nextPic 6 times and more?
ohho
Nope, the speed just keeps the same even after looping a cycle.
Anthony Chan