2010-09-24 64 views
15

我找不到一个像样的答案来解释这两个函数之间的区别。 什么时候每个人都会打电话,以及一个人和另一个人有什么不同?drawrect vs layoutsubviews - NSView - 可可触摸

例如,我不能只是布局我的意见里面drawrect?

感谢

回答

56

-layoutSubviews是,如果已经设置了“需要的布局”(使用-setNeedsLayout-layoutIfNeeded叫,或者当视图边界改变时自动)。用它来定位 您的看法 [编辑:用它来定位子视图]。

-drawRect:-displayIfNeeded如果“需要显示”标志(使用-setNeedsDisplay,或如果设置view.contentMode = UIViewContentModeRedraw自动)设定调用。

-layoutIfNeeded-displayIfNeeded都是在UIKit/CoreAnimation自动调用之前绘制屏幕;你很少需要直接打电话给他们。

可以在-drawRect:定位您的子视图(你甚至可以添加子视图!),但是这是不明智的:

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

编辑:有些时候我清醒,更详细:

什么是“显示”和“画”的区别?显示由-[CALayer display]完成;默认的实现为(大约)

  • 如果该层的委托回应-displayLayer:,调用[self.delegate displayLayer:self]-displayLayer:应该设置layer.content到(例如)一CGImage,
  • 否则,如果层的委托回应-drawLayer:inContext:,建立一个位图支持的情况下,打电话[self.delegate drawLayer:self inContext:context],并且输出保存到layer.content(输出实际上是一个CABackingStore ,这大概是一个私人API)
  • 否则,不改变layer.content

视图是层的委托,这样你就可以实现-[MyView displayLayer:]代替,并做一些有趣的东西一样

  • self.layer.contents = (id)([UIImage imageNamed:@"foo"].CGImage)(是的UIImageView做大致的)
  • 无操作,以防止任何“绘图”。如果你已经分类了,这可能会很有用。 UIToolbar并希望为其提供透明背景。 (这也可以防止CGContext上/ CABackingStore的创建。)
  • 移动子视图周围没有性能损失(但它仍然不是理由的好主意以上)。
+0

伟大的答案。谢谢! – Idan 2010-09-25 11:39:14

-2

也许我不知道所有的答案,但我可以说你是: - 当setNeedDisplay被称为

的drawRect被称为 - 当视图框改变 layoutSubviews被称为大多数时候你不会使用layoutSubviews。

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

好运的

+0

请给出更详细的在你的说法,“大部分的时间你不会用layoutSubviews。” – 2013-08-29 03:40:18