从零开始读MBProgressHUD(三)
-layoutSubviews和drawRect:
本文主要技术点如下:
- -layoutSubviews的主要作用
- -layoutSubviews的调用
- setNeedsLayout和layoutIfNeeded的区别
- 分析MBProgressHUD类的-layoutSubviews代码
- 分析MBProgressHUD类的drawRect:代码
-layoutSubviews的主要作用
-layoutSubviews是UIView的属性方法,顾名思义,其用来布局子控件,通常在应用开发中,我们在该方法中计算子控件的Frame。
-layoutSubviews调用
Subclasses can override this method as needed to perform more precise layout of their subviews. You should override this method only if the autoresizing and constraint-based behaviors of the subviews do not offer the behavior you want. You can use your implementation to set the frame rectangles of your subviews directly.
You should not call this method directly. If you want to force a layout update, call the setNeedsLayout method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded method.
大意如下:当你需要精确布局子控件时,可以重载-layoutSubviews实现。不能直接调用layoutSubviews,如需强制更新布局,调用setNeedsLayout,如需立即更新,调用layoutIfNeeded。
force和immediately好像不是那么容易理解,继续查阅官方文档:
setNeedsLayout解释如下:
Call this method on your application’s main thread when you want to adjust the layout of a view’s subviews. This method makes a note of the request and returns immediately. Because this method does not force an immediate update, but instead waits for the next update cycle, you can use it to invalidate the layout of multiple views before any of those views are updated. This behavior allows you to consolidate all of your layout updates to one update cycle, which is usually better for performance.
layoutIfNeeded解释如下:
Use this method to force the layout of subviews before drawing. Using the view that receives the message as the root view, this method lays out the view subtree starting at the root.
总的来说,调用setNeedsLayout会设置一个需要重新绘制的标记,但方法会立即返回,在下一次update cycle才会重新绘制子控件(通常性能更优);而layoutIfNeeded的调用会导致立即强制刷新绘制子控件
MBProgressHUD类的-layoutSubviews
以下代码说明HUD其实是完全遮盖住父控件的,即HUD显示时其superView不能响应用户交互:
UIView *parent = self.superview;
if (parent) {
self.frame = parent.bounds;
}
totalSize是进度条+提示文字+详情文字所占据的总共尺寸,计算后最后赋值给HUD的对象属性size. HUD正中间的进度条及文字部分背景颜色区别与HUD背景色clearColor,但并不是简单的给另一个view设置背景色,具体见下一篇关于drawRect:方法的分析.在这个size范围内可以添加一个交互手势,通过CGRectContainsPoint()判断落点是否在size范围内来处理响应事件.
MBProgressHUD类的drawRect:
drawRect:方法主要用于帮助开发者进行图形的绘制,在MBProgressHUD类的drawRect:方法中主要完成以下两个功能:
- 根据BOOL属性dimBackground判断是否需要绘制明暗渐变效果
- 根据-layoutSubviews计算的size绘制出HUD正中间进度条和文字的背景
绘制使用Quartz2D完成,在此不作赘述.