简体   繁体   中英

Poor UI performance when loading photos on iOS

I'm trying to make a photo slider similar to iOS's photos app. I've seen PhotoScroller , and I'm using initWithContentsOfFile .

CATiledLayer seems like a good idea, except I have no way of pre-generating tiles. The tiles also take up a lot of space. Images are part of a document bundle synced up with iCloud. Photos are typically JPEG. From hours of reading it seems like generating the tiles on the fly is slower than just loading the whole image.

It seems like a majority of the time is spent in decompressing the image anyway. And moving it to a background queue and displaying a smaller image should work well. So that's what I'm trying to do. And it works to a point, but if I slide without waiting for the image to load there's still somewhat of a stutter, which sometimes causes the scroll view to hang momentarily (when paging).

This is the function that sets the image:

- (void)setImage:(UIImage *)image placeholder:(UIImage *)placeholder
{
    _image = image;
    self.zoomScale = 1.0;
    imageView.image = nil;
    imageSize = image.size;
    imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
    MachTimer *timer = [MachTimer new];
    [timer start];
    imageView.image = placeholder;
    NSLog(@"placeholder: %f", [timer elapsedSeconds]);
    //imageView.layer.contents = (id)placeholder.CGImage;

    self.contentSize = image.size;
    [self setMaxMinZoomScalesForCurrentBounds];
    self.zoomScale = self.minimumZoomScale;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        MachTimer *timer = [MachTimer new];
        [timer start];
        UIGraphicsBeginImageContext(CGSizeMake(1, 1));
        [image drawAtPoint:CGPointZero];
        UIGraphicsEndImageContext();

        NSLog(@"decode: %f", [timer elapsedSeconds]);

        dispatch_sync(dispatch_get_main_queue(), ^{
            if(_image == image) {
                MachTimer *timer = [MachTimer new];
                [timer start];
                imageView.image = image;
                NSLog(@"display: %f", [timer elapsedSeconds]);
                //imageView.layer.contents = (id)image.CGImage;
            }
        });
    });
}

My "placeholder" times are about 0.00005 - 0.00006 seconds (decompress and display), and they're 480px tall. My "decode" times (for full image) are about 0.8 to 1.2 seconds. "display" is about 0.0001 seconds (which is about 0.1 milliseconds).

So with those times the UI should be smooth as butter, but it isn't.

I've even tried to go as far as setting contents of a regular UIView to the CGImage . I've tried iOS 6.0's drawsAsynchronously , and that seems to make it a little worse.

What am I doing wrong?

EDIT:

I've pushed my sample project to GitHub:

https://github.com/lukescott/PhotoScroller

我将创建一个后台线程来进行艰苦的工作(照片加载或解码),完成后再使用一种工具(队列,消息等)将UI工作(绘图或其他操作)委托给主线程。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM