代码之家  ›  专栏  ›  技术社区  ›  Idan

Drawrect与LayoutSubview-nsview-Cocoa Touch

  •  18
  • Idan  · 技术社区  · 14 年前

    我找不到合适的答案来解释这两种功能之间的区别。 每个人什么时候接到电话,一个和另一个有什么不同?

    例如,我不能在DrawRect中布局视图吗?

    谢谢

    2 回复  |  直到 9 年前
        1
  •  57
  •   skywinder Grady Player    9 年前

    -layoutSubviews 从调用 -layoutIfNeeded 如果设置了“需要布局”标志(使用 -setNeedsLayout 或在视图边界更改时自动更改)。用它来定位 你的观点 [ 编辑: 用它来定位 子视图 ]。

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

    两个 -必要时的布局 -需要时显示 由uikit/coreamination自动调用,然后将事物绘制到屏幕上;您很少需要直接调用它们。

    您可以将子视图放置在 -牵引力: (甚至可以添加子视图!)但这是不明智的:

    • 默认情况下, -设置需要显示 不会在边界更改时自动调用。
    • 实施 -牵引力: 降低性能(uikit/coreanimation必须为您创建支持位图的图形上下文);只有在需要执行自定义绘图时才这样做。
    • 您需要重新绘制视图 -牵引力: . 画画很贵。四处移动视野很便宜。
    • uikit/coreamination可能先执行布局过程,然后执行绘图过程。CoreAnimation可以使用布局信息来决定哪些视图需要绘制(例如,它可以忽略被不透明子视图、屏幕外视图或clipsToBounds=yes视图边界之外的子视图遮蔽的视图;或者它只能绘制大视图的子目录)。如果在绘图过程中移动视图,则CoreAnimation可能无法正确绘制视图。

    编辑: 当我醒着的时候还有更多的细节:

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

    • 如果层的委托响应 -displayLayer: ,呼叫 [self.delegate displayLayer:self] . -显示层: 应该设置 layer.content 到(例如)CGIMAGE,
    • 否则,如果层的委托响应 -drawLayer:inContext: ,设置支持位图的上下文,调用 [self.delegate drawLayer:self inContext:context] ,并将输出保存到 图层内容 (输出实际上是一个cabakingstore,这可能是一个私有API)
    • 否则,不要改变 图层内容 .

    视图是层的委托,因此可以实现 -[MyView displayLayer:] 相反,做一些有趣的事情,比如

    • self.layer.contents = (id)([UIImage imageNamed:@"foo"].CGImage) (这大致就是uiImageView所做的)
    • 禁止操作,以防止任何“绘图”。如果您已经对其进行了子类化(例如,uitoolbar),并且希望给它一个透明的背景,那么这可能很有用。(这也会阻止创建CGContext/CabackingStore。)
    • 在没有性能惩罚的情况下移动子视图(但出于上述原因,这仍然不是一个好主意)。
        2
  •  -2
  •   Vinzius    14 年前

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

    大多数时候你不会使用LayoutSubview。

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

    祝你好运