【问题标题】:How to combine setNeedsDisplay with a content scroll?如何将 setNeedsDisplay 与内容滚动结合起来?
【发布时间】:2013-04-02 01:35:42
【问题描述】:

我实现了一个自定义 UIView,它可以绘制无法以其他方式绘制的复杂图形(通过 drawRect)。由于绘制的项目在一个非常大的平面上(想想世界地图),由于内存限制,我无法使用 UIScrollView。我管理自己的原点和缩放变量,并根据这些变量绘制图形。我还实现了用于平移、放大和缩小、双击和单击等的手势识别器。这一切都很棒。

但我需要优化:当用户用他/她的手指平移时,我相应地更改我的内部原点变量并调用 setNeedsDisplay。这在模拟器和 iPhone 5 上运行良好,但在 iPad 3 上它有点慢(不算太糟糕,但仍然很明显)。我想要实现的是只为那些需要显示的区域(即屏幕上由于平移而显示的新到达项目)调用 setNeedsDisplay,并滚动(移动)已经在屏幕上的区域。显示屏幕的 1/10 会比显示 1/1 快得多,因为我已经进行了优化以快速确定哪些项目落在屏幕上并只显示那些。

换句话说,不是调用

thisView.originPoint = thisView.originPoint - 10;
[thisView setNeedsDisplay];

我希望我能以某种方式打电话

thisView.originPoint = thisView.originPoint - 10;
[thisView setNeedsDisplayInRect: CGMakeRect(320-10,0,320,480)
    withScroll: CGMakerect(0,0,320-10,480) scrollBy: CGPointMake(-10,0);

这显然只是程式化的代码。仅仅滚动视图的内容是没有帮助的(虽然我现在不知道怎么做),因为 drawRect 可能会在很久以后调用,并且可能与对 setNeedsDisplay 的另一个调用结合使用。

【问题讨论】:

    标签: ios uikit core-graphics


    【解决方案1】:

    在完全绘制视图后,您可以考虑使用[self.layer renderInContext:aContext]UIGraphicsGetImageFromCurrentImageContext() 缓存屏幕图像。当用户平移时,该图像可以绘制在不同的位置,例如。用户拖动时向左平移。同时,必要的数据也会被异步加载。在用户完成拖动或数据加载后,您可以设置一个标志,让 setNeedsDisplay 在所需部分绘制,然后缓存新图像。

    此外,CATiledLayer 类的功能与您正在寻找的类似,但需要对您已有的内容进行更多修改。

    希望这会有所帮助!

    【讨论】:

    • 不需要异步加载任何东西,因为所有数据都已经在内存中。我现在的想法是在 drawRect 中滚动以前绘制的东西,因为程序确切地知道之前绘制的内容。感谢您指出 CATiledLayer,这看起来也很有趣。
    • 不幸的是,缓存以前绘制的图像并将其用于下一个drawRect 在 iPad3 上与从头开始绘制图形一样慢。 [layer renderInContext][cachedImage drawAtPoint] 在 iPad3 上太慢了,无法平滑平移。
    • 嗯。我一直发现绘制图像比从头开始绘制更快(在我的情况下是 PDF,所以你的可能不是)。您是否尝试在从头开始绘制视图后立即在后台线程中渲染缓存图像?
    猜你喜欢
    • 2015-10-21
    • 1970-01-01
    • 2019-11-08
    • 2011-06-23
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    • 2012-03-17
    相关资源
    最近更新 更多