CATiledLayer in iPad retina simulator yields poor performance

六眼飞鱼酱① 提交于 2019-12-18 10:12:13

问题


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?


回答1:


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



回答2:


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.




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/9691891/catiledlayer-in-ipad-retina-simulator-yields-poor-performance

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