简体   繁体   English

使用layoutSubviews和drawRect自定义UIView绘图

[英]Custom UIView drawing with layoutSubviews vs drawRect

Should the drawing of CAShapeLayers be called from drawRect() or layoutSubviews() ? 是否应该从drawRect()layoutSubviews()调用CAShapeLayers的绘制?

According to Apple's documentation on UIViews, drawing operations should be placed in drawRect() . 根据Apple关于UIViews的文档,绘图操作应该放在drawRect()

However this is not the case in Kevin Cathey's WWDC Session: What's New in Interface Builder (where he demonstrates the process of building a custom UIView that is accessible in Interface Builder). 然而,在Kevin Cathey的WWDC会话中并非如此: Interface Builder中的新功能 (他演示了构建可在Interface Builder中访问的自定义UIView的过程)。

During his demonstration he performs the drawing of the view in layoutSubviews , rather than drawRect . 在演示期间,他在layoutSubviews执行视图绘制,而不是drawRect

His explanation was that: 他的解释是:

If I were to implement drawRect, that's not going to get us the best performance; 如果我要实现drawRect,那将无法让我们获得最佳性能; whereas, using sublayers and subviews is going to get us really good performance. 然而,使用子图层和子视图会让我们获得非常好的表现。

From what I've read so far on StackOverflow, it seems that overriding the drawRect() method can cause reduced performance. 从我到目前为止在StackOverflow上看到的内容来看,覆盖drawRect()方法似乎会导致性能降低。 This is partially due setNeedsDisplay triggering manual redraws being expensive. 这部分是由于setNeedsDisplay触发手动重绘很昂贵。

But looking through the Apple Documentation and real world applications. 但仔细查看Apple文档和实际应用程序。 It makes sense that drawRect() should be responsible for the drawing of the View, and layoutSubviews() handling positioning. 有意义的是, drawRect()应该负责View的绘制, layoutSubviews()处理定位。

I would say it depends. 我会说这取决于。 If the size of your shape is going to be dependent on the Auto Layout system then it might be beneficial to do the drawing in Layout Subview versus Draw Rect. 如果形状的大小将取决于自动布局系统,那么在布局子视图和绘制矩形中进行绘制可能是有益的。

First, why would layout subviews ever have better performance? 首先,为什么布局子视图会有更好的表现? Well say I have a UIView (my parent view) that is drawing a Circle View (my subview) which is using a shape layer. 好吧,我有一个UIView(我的父视图)正在绘制一个使用形状图层的圆形视图(我的子视图)。 The size of that circle is determined by a Width and Height constraint in my Parent View. 该圆的大小由我父视图中的宽度和高度约束确定。 I only ever need to redraw the circle when either the width/height constraints are changed on the Parent View. 在父视图中更改宽度/高度约束时,我只需要重绘圆圈。 This is an instance where it is beneficial to have the drawing code in Layout Subviews because I only ever need to redraw the shape layer when the constraints change. 这是一个在布局子视图中使用绘图代码是有益的实例,因为我只需要在约束更改时重绘形状图层。 Let's see the Auto Layout cycle 我们来看看自动布局循环

  1. Update Constraints 更新约束
  2. Layout Subviews 布局子视图
  3. Render the Views 渲染视图

By the time layout subviews is called we know the size of the frame we are working with and can safely perform our drawing. 当布局子视图被调用时,我们知道我们正在使用的框架的大小,并且可以安全地执行我们的绘图。 I know the documentation says you should use this method to just set the frame, bounds, etc. However, drawing within the frame doesn't sound unreasonable depending on the circumstances. 我知道文档说你应该使用这个方法来设置框架,边界等。但是,根据具体情况,在框架内绘图并不合理。

If the Circle View isn't dependent upon the Auto Layout system and could be changed at anytime regardless of the layout of the UI, then it would probably be more beneficial to have the drawing in draw rect so it can constantly be updated. 如果圆形视图不依赖于自动布局系统,并且可以随时更改,无论UI的布局如何,那么将绘图绘制为绘制矩形可能更有利,因此可以不断更新。 I think this is less than an ideal situation as more UI's in iOS conform to using Auto Layout, hence the recommendation of using Layout Subviews. 我认为这不是一个理想的情况,因为iOS中的更多UI符合使用自动布局,因此建议使用布局子视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM