iPad视网膜模拟器中的CATiledLayer性能不佳

时间:2012-03-13 20:48:26

标签: ios ipad catiledlayer retina-display

我希望也许这只是模拟器的一个问题但当然让我担心,因为我已经提交了我的视网膜应用程序,直到16日才能测试它。

我在我的应用中实现了CATiledLayer来查看非常大的地图。地图的图块来自互联网,但它们也会被缓存,因此,通常它们实际上是直接从设备加载的。

在iPad 1和iPad2上,它的工作效果非常好。您只能注意到iPad 2上呈现的图块,即使它们来自互联网也是如此。

在iPad模拟器上它运行得很漂亮。

我的问题是iPad视网膜模拟器。在视觉上,它看起来没问题。地图的大小正确,并与我用来显示数据叠加层的另一个图层对齐,但是它会慢慢加载。在我尝试的大部分时间里,在我开始滚动之前它根本不会加载任何图块,然后当 加载图块时它可能每秒执行1次并且看起来很糟糕。

我没有在视网膜上运行的代码比标准分辨率屏幕不同,所以我希望这只是模拟器的一个问题......但我仍然担心。

有没有其他人在他们自己的应用程序中看到过这个?

4 个答案:

答案 0 :(得分:14)

较大的磁贴大小对我有用,但是当我调整CATiledLayer的levelsOfDetailBias属性时,它会回到制作小磁贴并且需要永远加载。关闭细节偏差是不可接受的,因为放大视图需要看起来很清晰,所以我看了一些Apple的文档 - https://web.archive.org/web/20120323033735/http://developer.apple.com/library/ios/samplecode/ZoomingPDFViewer/Listings/Classes_PDFScrollView_m.html - 他们的一个建议是覆盖平铺视图的layoutSubviews方法以始终设置contentScaleFactor = 1.之后我唯一需要做的就是每次调用scrollViewDidEndZooming时调用setNeedsLayout。这假设您使用的是UIScrollView。我在我的iPad(第三代)和iPad2上进行了测试,两者似乎都运行良好。希望有所帮助。

示例代码 - 假设您正在继承UIView并使用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;
    }

然后假设您的View Controller设置为UIScrollViewDelegate -

    -(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale{
        //do any other stuff you may need to do.
       [view setNeedsLayout];
    }

答案 1 :(得分:4)

所有TiledLayers的iPad3性能都比iPad2差 - 这在GoogleMaps应用程序中也很明显。

但是,通过向使用CATiledLayer的UIView类添加以下更改可获得最佳性能

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

还有其他选项可以直观地实现相同的结果,即增加tileSize但性能会更差。

答案 2 :(得分:3)

模拟器上的CATiledLayer性能似乎与实际新iPad上的性能完全不同。测试实际硬件。

CATiledLayer在新iPad上生成的瓷砖比在旧设备上生成的瓷砖多得多,即使使用相同的设置也是如此。目前,我检测代码是否在招聘屏幕上运行(通过CALayer的contentScale属性),如果是,请设置更大的磁贴大小。

我会做更多的实验,并会在这里发布任何重要的发现。

答案 3 :(得分:0)

请记住,它只是一个模拟器,它很可能是软件加速的。另一方面,该设备是硬件加速的,并且Core Animation经过高度优化,因为只需要很少的目标GPU。

在你检查新iPad本身的表现之前,我不会关心模拟器的结果。

相关问题