如何使用 Quartz 在 UIView 上绘制子视图

Posted

技术标签:

【中文标题】如何使用 Quartz 在 UIView 上绘制子视图【英文标题】:How to draw a subview onto UIView using Quartz 【发布时间】:2011-08-17 06:13:52 【问题描述】:

我正在 iPad 应用程序的 UIView 上生成并显示树结构。我们将视图称为 ROOTVIEW。所有的树节点也是 UIViews,它有 label 和 UIImage 作为子视图。当从数据源生成节点时,它会为该节点生成一个 UIView 并作为子视图添加到 ROOTVIEW。但问题是,当树结构很大时,比如数千个节点,它会使用太多的内存。

由于添加到ROOTVIEW后节点的视图不会改变,所以我想出了一个解决方案:当我们得到节点的UIView时,不将其作为子视图添加到ROOTVIEW中,而是将其绘制在ROOTVIEW上,然后释放节点的界面视图。所以最后只有一个视图:ROOTVIEW。

我对 Quartz 不太熟悉,如何在 UIView 上绘制子视图?谢谢。

【问题讨论】:

【参考方案1】:

是的,这是正确的方法。只需在根图像视图上渲染单个视图甚至部分视图树。 在此处查看如何执行此操作:Easy or efficient way to copy the bitmap representation from one view to another?

【讨论】:

谢谢,我想这就是我想要的。但是我怎样才能迭代地绘制图像呢?我只能想到使用上述方法存储从子视图生成的图像并存储在根视图中。当要求显示根视图时,然后使用 drawRect 将所有图像绘制到根视图。但它也会使用太多的内存。如何在生成子视图图像时将其绘制到根视图然后丢弃图像? renderInContext 方法将整个视图的树渲染为单个图像。因此无需使用 drawRect。使用单个 UIImageView 作为根视图,然后将整个树渲染到其中并释放树,或者迭代地渲染每个视图而不是将其添加到树中。或者您可以迭代地添加由节点制作的图像。【参考方案2】:

您是否考虑过使用UITableView?我知道它不直接支持嵌套节点,但您最好还是利用UITableViewController 的功能,而不是实现一个完整的树组件。您可以尝试将单元格自定义为缩进,以实现树状视觉效果。

HTH,

阿克谢

【讨论】:

【参考方案3】:

除了使用 UITableView 的建议之外,您还可以考虑使用自己的树节点视图的缓存。这意味着您拥有一组树节点视图,并回收它们 - 每当用户滚动时,都会显示不同的数据,但(几乎)显示相同数量的树节点。只需分配足够的树节点来填充可见区域,可能还有两到三个用于滚动边缘,并且每次用户滚动时,更新每个树节点中的数据。 UITableview 中使用了相同的技术,它保存了可以显示的单元格数量(通常为 14-20,取决于单元格高度),UITalbleView 不会为表格中的行数分配单元格(可能是成百上千!)

【讨论】:

我知道,但是在我的应用程序中,要求用户可以看到整个树的概览并放大和缩小以探索树。 哎哟。考虑直接将整个内容绘制到图形上下文(覆盖 DrawRect),或绘制到离线图像并根据需要缩放该图像。 整个树的概览是什么意思?如果您的树有数百个节点,您将如何显示概览?我建议你重新考虑你的 UI 设计。

以上是关于如何使用 Quartz 在 UIView 上绘制子视图的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UIView 下绘制阴影?

Quartz 2D绘制简单图形

如何使用quartz2d/coregraphics绘制圆角三角形

UIView 在子视图中绘制

UIView 需要很长时间才能显示

iOS平台如何画线