从头开始 UIScrollView 和 CATiledLayer

发布于 2024-10-03 22:15:32 字数 439 浏览 0 评论 0原文

我的情况:我创建了一个 UIScrollView ,其中有一个 UIView ,其中调用一个 Graph 类,该类在上下文上绘制一个漂亮的图形。 现在我发现如果 UIView 的宽度大于 8192 像素,手机就不会渲染它。事实上,根据Apple的文档,如果我想要它大于1024px,我应该实现CATiledLayer。

但经过大量阅读和谷歌搜索后,我仍然发现很难理解用于此任务的 CATiledLayer 基础知识 - 我在 Quartz 与 Cocoa 以及层和子层与视图和子视图之间不知何故迷失了。

理想情况下,我希望保持 Graph 类不变,只需完全绘制上下文,将其拆分为图块并滚动它们。滚动视图应该只是水平滚动,不需要缩放或垂直滚动​​。这可能吗?如果是这样,我应该如何继续? 也许有人可以给我一个大纲,只是一些要点或伪代码,我应该如何重构滚动视图、uiview 和图形类以使用平铺。

预先非常感谢您的回复。

my situation: I created an UIScrollView with an UIView inside which calls a Graph class which draws a nice graph on a context.
Now I discovered that the phone wouldn't render the UIView if it's width is larger than 8192 pixels. In fact, according to Apple's docs, if I want it larger than 1024px, I should implement CATiledLayer.

But after reading and googling a lot, I still find it difficult to understand the basics of CATiledLayer for this task-I'm somehow lost between Quartz vs. Cocoa and layers and sublayers vs. views and subviews.

Ideally I would like to keep the Graph class untouched, just draw the context entirely, split it into tiles and scroll those. The scrollview should just scroll horizontal, no zooming or vertical scrolling required. Is that possible? If so, how should I continue?
Perhaps someone could give me an outline, just some bulletpoints or pseudocode, how I should restructure the scrollview, uiview and the graph class to use tiling.

Thank you very much in advance for any reply.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酒中人 2024-10-10 22:15:32

你问这个问题已经过去一个月了,但这可能仍然有用。我今晚刚刚开始使用 CATiledLayer。我认为 CATiledLayer 背后的想法似乎是将其添加到视图中:

CATiledLayer *tiled = [CATiledLayer layer];
[self.view.layer addSublayer:tiled];

并且设置一个委托,仅实现一种方法:

MyTLDelegate *myDelegate = [[MyTLDelegate alloc] init];
tiled.delegate = myDelegate;
// I haven't checked if CATiledLayer retains myDelegate, check this!

...
@implementation MyTLDelegate {

-(void)drawLayer:(CATiledLayer *)layer inContext:(CGContextRef)ctx
{
    CGRect dirtyRect = CGContextGetClipBoundingBox(ctx);
    // draw!
}

这基本上就是它的全部内容,您可以绘制就好像整个坐标空间只是那里。因此,您只需要稍微修改 Graph 类,使其可以充当 CATiledLayer 委托。就我而言,这 20 分钟的花费非常值得,将用户体验提升了几个数量级。 (与我自己进行繁琐的滚动、缩放和重画相比

)这只是您要求的伪代码,您可能需要一些额外的粘合剂才能使事情顺利进行,例如质量和/或帧大小。

It's been a month since you asked but this may still be of use. I just started using CATiledLayer tonight. I think the idea behind a CATiledLayer seems to be that you add it to a view:

CATiledLayer *tiled = [CATiledLayer layer];
[self.view.layer addSublayer:tiled];

and that you set a delegate, implementing just one method:

MyTLDelegate *myDelegate = [[MyTLDelegate alloc] init];
tiled.delegate = myDelegate;
// I haven't checked if CATiledLayer retains myDelegate, check this!

...
@implementation MyTLDelegate {

-(void)drawLayer:(CATiledLayer *)layer inContext:(CGContextRef)ctx
{
    CGRect dirtyRect = CGContextGetClipBoundingBox(ctx);
    // draw!
}

That's basically all there is to it, you can just draw as if the entire coordinate space is just there. So you should only need to slightly modify your Graph class so it can act as a CATiledLayer delegate. In my case it was 20 minutes well spent, boosting user experience by several orders of magnitude. (compared to doing the tedious scrolling, scaling and redrawing myself)

ps. this is only the pseudo code you asked for, you may need some extra glue to get things going, e.g. for quality and/or frame sizes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文