I need to let user navigate back and forward through different images (from 10 to 20) with a tap.
All the images are 1024x768 JPG's so I don't need to resize or transform them. There are no animations betwe开发者_JAVA技巧en them (I'll switch them with a removeFromSuperView and addSubView). All I want is avoid loading time or unresponding touch, so I actually was thinking about these possible solutions:- Load each image singularly on tap;
- Load 3 images: previous, actual and next one;
- Load an array or a uiviewimage with all the images and iterate through it;
I will avoid imageNamed and I'll use imageWithContentOfFile or imageWithData.
Which solution do you think is the best one? Could solutions 1. and 3. bring some performance issue?Method 1 will be good : iOS devices can load full screen images really fast. Especially if your images don't have alpha. It will depends on images but it takes around 0.05 seconds for a classic png. This means that users will not notice the waiting time if you have to change after a tap especially if you had a fade transition between images.
Things can get harder if user can scroll through images. In this case, I would advise to use UITableView. They behave like UISCrollView and they load/unload pages fastly and smoothly.
To get an horizontal table view, you can use this code which works perfectly : https://github.com/alekseyn/EasyTableView
If your upper limit for number of images is 20, just preload an array of UIImages, and set the UIImageView.image property on response to touch - don't worry about swapping views, reusing a single UIImageView will be fine.
I wouldn't worry about performance unless the upper limit rises much higher - if it does, a dynamic cache like option 2 would be a better choice, but more programming.
If you are concerned about performance in an iPad application destined for the app store, always remember to test on a first generation iPad, since there was a major performance jump after the original.
I have actually done this before. With large images, you are going to have to be careful with memory. I originally loaded all of my images into an NSArray but I experienced memory warning and crashes.
My implementation uses a UIScrollView with paging. I have to arrays, one contains all of the image names and the other is mutable and contains only a few UIImageViews. I record the current 'page' that the scroll view is on, and when I land on an image I ensure that the mutable array contains that image and two images on either side of it (and remove any other images from the array).
The problem with this implementation is that you keep having to read images from disk which will be slow on the main thread. Sooo when I initially create the UIImageViews I add a UIActivityIndicator to them. Then, I pass my array of UIImageViews to a method in the background that actually loads the UIImage and then makes the respective UIImageView set the image on the main thread like so:
// called before you try to load an image in a background thread
[imageView addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
// called in the background thread after you load the image from disk
[imageView performSelectorOnMainThread:@selector(setImage:) withObject:fullImage waitUntilDone:NO];`
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
UIImageView *imageView = (UIImageView *)object;
[[imageView viewWithTag:1] removeFromSuperview]; // this is the activity indicator
[imageView removeObserver:self forKeyPath:@"image"];
}
精彩评论