drawrect Vs layoutsubviews - NSView - Cocoa touch

时间:2010-09-24 17:28:27

标签: iphone cocoa-touch nsview drawrect

我找不到合适的答案来解释这两个功能之间的区别。 每个人什么时候被调用,一个人与另一个人有什么不同?

例如,我不能只在drawrect中布置我的视图吗?

由于

2 个答案:

答案 0 :(得分:57)

如果设置了“layout needed”标志(使用-layoutSubviews,或者在视图边界发生变化时自动设置),则从-layoutIfNeeded调用{p> -setNeedsLayout。用它来定位你的视图 [编辑:用它来定位子视图]。

如果设置了“需要显示”标记(使用-drawRect:,则会-displayIfNeeded调用-setNeedsDisplay,如果设置view.contentMode = UIViewContentModeRedraw,则会自动调用-layoutIfNeeded

在将事物绘制到屏幕之前,UIKit / CoreAnimation会自动调用-displayIfNeeded-drawRect:;你很少需要直接打电话。

您可以将您的子视图放在-setNeedsDisplay中(您甚至可以添加子视图!),但这是不明智的:

  • 默认情况下,在边界更改时不会自动调用-drawRect:
  • 实现-drawRect:会降低性能(UIKit / CoreAnimation必须为您创建一个支持位图的图形上下文);只有在需要执行自定义绘图时才这样做。
  • 您需要在-[CALayer display]中重绘视图。绘图很贵。移动视图很便宜。
  • UIKit / CoreAnimation可能会进行布局传递,然后是绘图传递。 CoreAnimation可以使用布局信息来决定需要绘制哪些视图(例如,它可以忽略由不透明子视图,屏幕外视图或者在clipsToBounds = YES视图范围之外的子视图遮挡的视图;或者它只能绘制一个子视图大观)。如果在绘图过程中移动视图,CoreAnimation可能无法正确绘制它们。

编辑:当我醒来时还有一些细节:

“显示”和“抽奖”有什么区别?显示由-displayLayer:完成;默认实现是(大约)

  • 如果图层的代理人回复[self.delegate displayLayer:self],请致电-displayLayer:layer.content应该将-drawLayer:inContext:设置为(例如)CGImage,
  • 否则,如果图层的委托响应[self.delegate drawLayer:self inContext:context],请设置支持位图的上下文,调用layer.content,并将输出保存到layer.content(输出实际上是CABackingStore,这可能是私人API)
  • 否则,请勿更改-[MyView displayLayer:]

视图是图层的委托,因此您可以实现self.layer.contents = (id)([UIImage imageNamed:@"foo"].CGImage),并执行有趣的操作,例如

  • {{1}}(大致与UIImageView相同)
  • 禁止操作,以防止任何“绘图”。如果您已经将子类化,例如,这可能很有用。 UIToolbar并希望给它一个透明的背景。 (这也会阻止创建CGContext / CABackingStore。)
  • 在没有性能损失的情况下移动子视图(但由于上述原因,它仍然不是一个好主意。)

答案 1 :(得分:-2)

也许我没有所有的答案,但我可以这样说: - 更改视图框架时调用layoutSubviews - 调用setNeedDisplay时调用drawRect

大多数情况下,您不会使用layoutSubviews。

可能还有其他情况,但它可以给你第一个答案^^

祝你好运