setNeedsDisplay不会按预期触发子视图中的drawRect

时间:2012-07-14 01:41:54

标签: objective-c subview drawrect setneedsdisplay

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

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

TrollCalendarView有7个名为PlatformView的子视图,旨在包含以{7}排列在TrollCalendarView中心周围的2D绘图对象。因此,当iPad旋转时,这7个视图会旋转,使得它们始终以主要方向定向。

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

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

TrollCalendarView我添加了滑动识别器。当我滑动时,属性会更新,我会调用[self setNeedsDisplay]但似乎没有任何事情发生。我在每个视图中向drawRect:方法添加了NSLog条目,并且只调用了TrollCalendarView drawRect:方法。具有讽刺意味的是,这是drawRect方法为空的一个视图。

没有xib文件。

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

2 个答案:

答案 0 :(得分:8)

  

我正在努力使用setNeedsDisplay。我认为它应该触发drawRect调用它被调用的视图和下面的层次结构,如果它在视图的范围内

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

-setNeedsDisplay:仅适用于发送它的视图。如果您需要使其他视图无效,则还需要添加一些代码以向其发送-setNeedsDisplay:。这就是它的全部内容。

答案 1 :(得分:5)

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

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

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

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