CATiledLayer in iPad retina simulator yields poor performance

大城市里の小女人 提交于 2019-11-29 20:12:37
mzider

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];
    }

The performance on iPad3 of all TiledLayers is worse than on iPad2 - that's also visible in the GoogleMaps app.

However, the best performance you get by adding the following changes to your UIView class that uses CATiledLayer

- (id)initWithFrame:(CGRect)frame tileSize:(CGSize)tileSize
{
    self = [super initWithFrame:frame];
    if(self)
    {
        CATiledLayer *animLayer = (CATiledLayer *) self.layer;
        animLayer.levelsOfDetail = 5;
        animLayer.levelsOfDetailBias = 3;
        animLayer.tileSize = tileSize;

        // adjustments for retina displays
        if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00)
        {
            animLayer.contentsScale = 1.0;
            self.contentScaleFactor = .5;
            animLayer.shouldRasterize = NO;
            animLayer.levelsOfDetailBias ++;
        }
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00)
    {
        self.contentScaleFactor = .5;
    }
}

There are other options to achieve the same result visually ie increasing tileSize but the performance will be much worse.

CATiledLayer performance on the simulator seems to be nothing like that of that on an actual new iPad. Test on actual hardware.

CATiledLayer generates a lot more tiles on the new iPad than on older devices, even when using the same settings. At the moment I detect whether the code is running on a hires screen (via CALayer's contentScale property), and if so, set a bigger tile size.

I'll be doing more experimentation, and will post any significant findings here.

Remember, it's just a simulator and it's most likely software accelerated. On the other hand, the device is hardware accelerated and Core Animation is highly optimized, since there are only few target GPUs to look for.

Until you check your performance on the new iPad itself I wouldn't be concerned with simulator results.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!