setNeedsDisplay 未按预期在子视图中触发 drawRect

Posted

技术标签:

【中文标题】setNeedsDisplay 未按预期在子视图中触发 drawRect【英文标题】:setNeedsDisplay does not trigger drawRect in subviews as expected 【发布时间】:2012-07-14 01:41:53 【问题描述】:

我正在为setNeedsDisplay 苦苦挣扎。我认为它应该为调用它的视图触发drawRect: 的调用,如果它在视图的范围内,那么它下面的层次结构,但我发现情况并非如此。这是我的设置:

从应用程序委托中,我创建了一个大小为正方形的视图,基本上覆盖了整个屏幕空间。此视图称为TrollCalendarViewTrollCalendarView 除了由指南针触发的旋转外,不会发生太多变化。

TrollCalendarView 有 7 个子视图,称为 PlatformView,旨在包含以 7 面排列的方式围绕 TrollCalendarView 的中心排列的 2D 绘图对象。因此,当 iPad 旋转时,这 7 个视图会旋转,因此它们始终与基本方向一致。

每个PlatformView 子视图都包含3 个名为Tower 的子视图。每个塔都包含在drawRect: 中实现的二维绘图对象。

所以,总而言之,我有 TrollCalendarView 和空的 drawRect:,以及子视图 PlatformViewPlatformview -> 每个都有 drawRect 实现的 Tower。此外,Tower 位于 Platform 范围内,Platform 位于 TrollCalendarView 范围内。

TrollCalendarView 中,我添加了一个滑动识别器。当我刷卡时,属性被更新,我打电话给[self setNeedsDisplay],但似乎什么也没发生。我在每个视图中将 NSLog 条目添加到 drawRect: 方法,并且只调用了 TrollCalendarView drawRect: 方法。具有讽刺意味的是,这是一个视图,其drawRect 方法将为空。

没有xib文件。

我需要做些什么来确保调用其他子视图中的drawRect 方法?是否有文档描述了可能影响这一点的所有细微差别?

【问题讨论】:

【参考方案1】:

我正在为 setNeedsDisplay 苦苦挣扎。我认为它应该触发对调用它的视图的 drawRect 调用,如果它在视图的范围内,则它下面的层次结构

不,事实并非如此。你是从哪里得到这个想法的?

-setNeedsDisplay: 仅适用于它被发送到的视图。如果您需要使其他视图无效,您也需要添加一些代码以将-setNeedsDisplay: 发送给它们。仅此而已。

【讨论】:

我从 *** 上类似问题的答案中得到了这个想法。只需在子视图 setNeedsDisplay 中搜索示例。有好几个。 除非我知道其他方法,否则我将遵循此建议。它至少符合我在测试中的发现。 不幸的是,在 SO 上有很多噪音和很多盲目的引导。您正在查看的问题的票数很少,因此可能没有多少人看过它们或有机会纠正它们。如果您刚刚开始,Apple 文档会可靠得多。 谢谢。在我发送到所有相关视图之后它就起作用了。【参考方案2】:

我认为这是对框架的优化;如果您的子视图需要再次绘制,那么这是一个重大的性能改进。意识到几乎任何可动画的东西都不需要 drawrect(移动、缩放等)。

如果您知道应该重绘所有子视图(而不是简单地移动),然后在主视图中覆盖 setNeedsDisplay 并执行以下操作:

-(void) setNeedsDisplay 
    [self.subviews makeObjectsPerformSelector:@selector(setNeedsDisplay)];
    [super setNeedsDisplay];

我已经对此进行了测试,它也会导致所有子视图都被重绘。请注意,如果您以某种方式过滤子视图并确保仅将其发送到实际上需要重绘的子视图,您将获得效率业力点...如果您能弄清楚如何不需要重新绘制它们。 :-)

【讨论】:

谢谢。我会试试的。在我的场景中,不需要重绘 7 个平台子视图。剩下的 21 个子视图中的三分之二将保证需要重绘。知道哪 21 个需要重绘是在 drawRect 中有效计算的,并且不能在其他地方更有效地完成。只是好奇-框架如何否决我的决定(您的优化评论)?似乎这违背了首先设置 setNeedsDisplay 的目的。 不。不工作。这仅获取子视图。我需要重绘这些子视图的子视图。我决定在我需要设置 setNeedsDisplay 的地方进行遍历树的工作。不过,感谢您的建议。

以上是关于setNeedsDisplay 未按预期在子视图中触发 drawRect的主要内容,如果未能解决你的问题,请参考以下文章

iOS Storyboard 约束未按预期运行

自动布局约束未按预期工作

UIScroll 视图未按预期工作

对于 UITableView.tableHeaderView 的子视图,autoresizingMask 未按预期工作

为啥模态演示表单未按预期显示?

嵌入 ViewController 时视图未按预期使用 AutoLayout 进行布局