Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CATiledLayer in iPad retina simulator yields poor performance

I'm hoping maybe this is just an issue with the simulator but of course it has me worried since I have already submitted my retina capable apps and there's no way to test it until the 16th.

I have implemented a CATiledLayer in my app to view very large maps. The tiles for the map are coming from the internet, however they also get cached, so, typically, they are actually being loaded directly from the device.

On iPad 1 and iPad2 it works beautifully. You can only barely notice the tiles being rendered on the iPad 2, even when they are coming from the internet.

On the iPad Simulator it works beautifully.

My problem is the iPad retina simulator. Visually, it looks okay. The map is sized properly and lines up with another layer I use to display a data overlay, however it loads INCREDIBLY slowly. Most of the time I try, it won't load any tiles at all until I begin scrolling, then when it is loading tiles it's doing maybe 1 per second and looks terrible.

I have no code that would run differently on the retina than the standard resolution screen, so I'm hoping this is just an issue with the simulator...but I'm still concerned.

Has anyone else seen this in their own apps?

like image 467
Brodie Avatar asked Mar 13 '12 20:03

Brodie


1 Answers

Bigger tile sizes were kind of working for me, however when I would adjust the levelsOfDetailBias property of the CATiledLayer, it would go back to making tiny tiles and it would take forever to load. Turning off detail biasing was unacceptable as zooming into the view needed to look sharp, so I looked at some of Apple's docs - https://web.archive.org/web/20120323033735/http://developer.apple.com/library/ios/samplecode/ZoomingPDFViewer/Listings/Classes_PDFScrollView_m.html - and one of their suggestions was to override the layoutSubviews method of your tiled view to always set the contentScaleFactor = 1. The only thing I had to do after that was call setNeedsLayout every time scrollViewDidEndZooming fired. This is assuming you are using a UIScrollView. I have tested this on my iPad(3rd Gen) and iPad2, both seem to work very well. Hope that helps.

Example Code - Assuming you are subclassing a UIView and overriding the view's backing layer with a CATiledLayer -

     -(void)layoutSubviews{
        [super layoutSubviews];
        /* 
           EDIT: After some additional experimentation, 
           I Have found that you can modify this number to .5 but you need
           to check to make sure you are working on a 3rd gen iPad. This
           seems to improve performance even further.
        */

        // Check if app is running on iPad 3rd Gen otherwise set contentScaleFactor to 1
        self.contentScaleFactor = .5;
    }

then assuming your View Controller is setup as a UIScrollViewDelegate -

    -(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale{
        //do any other stuff you may need to do.
       [view setNeedsLayout];
    }
like image 105
mzider Avatar answered Nov 09 '22 05:11

mzider