Search code examples
iphoneuiscrollviewuiimageviewcore-animationcatiledlayer

Zooming and Scrolling large images in UIScrollView


I've been stuck at this for quite some time. I've looked at many other answers and also at Apple's examples.

What I want to know is how I can go about loading large images in UIScrollView, and be able to page through them and zoom in to them, like the Photos app.

I'm working on an app where I need to scroll through large images (by large, I mean images greater than 1024 x 1024). I've already implemented something similar to what the photos app does. However, now that I'm using large images, I get memory warnings and stuff. I know why I'm getting the warning, and I know that I need to Tile the images.

Apple's examples demonstrate tiling with small images which are already present. My app will be downloading multiple images, saving them on a disk and the user will be able to look at them at a later time. Thus, I cannot have the images cut up using other programs.

I need something wherein I can tile the full size images. Any help will be greatly appreciated. Additionally, as I mentioned earlier, I know that I have to do something with Tiling. However, I'm new to this, and I would greatly appreciate if the answers contain some sample code, which I can use as a start off point.

I've looked at other questions, and none seemed to have been answered to my satisfaction, owing to which, I'm asking this question again.

Thanks again!


Solution

  • To work with tiling you'll need to use a CaTiledLayer in your view. Googling for it will give you good information. Basically you declare that the UIVIew is using it, declare some levels of details for zooming and in the drawRect you'll receive each tile as the rect parameter.

    To tile the image, load in a UIImage (it uses memory, but quite less than showing it) and use for each tile you want something like:

    UIGraphicsBeginImageContextWithOptions(tileSize, YES, 1);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(ctx, -tileSize.width * columnNumber, -tileSize.height*rowNumber);
    [img drawInRect:CGRectMake(0, 0, tileSize.width, tileSize.height)];
    UIImage* imgCut = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

    and save imgCut. You probably will want to generate tiling with different zooms if you use different level of detail in your CATiledLayer.