iOS開發:setNeedsLayOut和setNeedsDisplay區別


layoutSubviews方法
 
根據蘋果官方幫助文檔對layoutSubviews方法的解釋:

    此方法用來重新定義子元素的位置和大小。當子類重寫此方法,用來實現UI元素的更精確布局。如果要讓布局重新刷新,那么就調用setNeedsLayout,即setNeedsLayout方法會默認用layoutSubViews方法。

很多時候系統會自動調用layoutSubviews方法:

  1.初始化不會觸發layoutSubviews,但是如果設置了不為CGRectZero的frame的時候就會觸發。
  2.addSubview會觸發layoutSubviews
  3.設置view的Frame會觸發layoutSubviews,當然前提是frame的值設置前后發生了變化
  4.滾動一個UIScrollView會觸發layoutSubviews
  5.旋轉Screen會觸發父UIView上的layoutSubviews事件
  6.改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件

 

注:setNeedsLayout方法並不會立即刷新,立即刷新需要調用layoutIfNeeded方法。

 
setNeedsDisplay方法
 
與setNeedsLayOut方法相似的方法是setNeedsDisplay方法。該方法在調用時,會自動調用drawRect方法。drawRect方法主要用來畫圖。
 
總結
所以,當需要刷新布局時,用setNeedsLayOut方法;當需要重新繪畫時,調用setNeedsDisplay方法。
 

延伸:

當我們自定義UI控件時,需要重寫一些方法:

UIView控件只是一個矩形的空白區域並沒有任何內容。iOS應用的其他UI控件都繼承了UIView這些UI控件都是在UIView提供的空白區域上繪制外觀。

基於UI控件的實現原理開發者完全可以開發出項目定制的控件——當iOS系統提供的UI控件不足以滿足項目需要時開發者可以通過繼承UIView來派生自定義控件。

當開發者打算派生自己的UI控件時首先定義一個繼承View基類的子類然后重寫View類的一個或多個方法通常可以被用戶重寫的方法如下。

initWithFrame:前面已經見到程序創建UI控件時常常會調用該方法執行初始化因此如果你需要對UI控件執行一些額外的初始化即可通過重寫該方法來實現。

initWithCoder:程序通過在nib文件中加載完該控件后會自動調用該方法。因此如果程序需要在nib文件中加載該控件后執行自定義初始化則可通過重寫該方法來實現。

drawRect:如果程序需要自行繪制該控件的內容則可通過重寫該方法來實現。

layoutSubviews如果程序需要對該控件所包含的子控件布局進行更精確的控制可通過重寫該方法來實現。

didAddSubview:當該控件添加子控件完成時將會激發該方法。

willRemoveSubview:當該控件將要刪除子控件時將會激發該方法。

willMoveToSuperview:當該控件將要添加到其父控件中時將會激發該方法。

didMoveToSuperview當把該控件添加到父控件完成時將會激發該方法。

willMoveToWindow: 當該控件將要添加到窗口中時將會激發該方法。

didMoveToWindow當把該控件添加到窗口完成時將會激發該方法。

touchesBegan:withEvent:當用戶手指開始觸碰該控件時將會激發該方法。

touchesMoved:withEvent:當用戶手指在該控件上移動時將會激發該方法。

touchesEnded:withEvent:當用戶手指結束觸碰該控件時將會激發該方法。

touchesCancelled:withEvent:用戶取消觸碰該控件時將會激發該方法。

當需要開發自定義View時開發者並不需要重寫上面列出的所有方法而是根據業務需要重寫上面的部分方法。例如下面的跟隨手指運動的小球示例程序就只重寫drawRect:方法。

 
#import "FKCustomView.h"
@implementation FKCustomView
// 定義兩個變量記錄當前觸碰點的坐標
int  curX;
int  curY;
- ( void ) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
     // 獲取觸碰事件的UITouch事件
     UITouch *touch = [touches anyObject];
     // 得到觸碰事件在當前組件上的觸碰點
     CGPoint lastTouch = [touch locationInView:self];
     // 獲取觸碰點的坐標
     curX = lastTouch.x;
     curY = lastTouch.y;
     // 通知該組件重繪
     [self setNeedsDisplay];
}
// 重寫該方法來繪制該UI控件
- ( void )drawRect:(CGRect)rect
{
     // 獲取繪圖上下文
     CGContextRef ctx = UIGraphicsGetCurrentContext();
     // 設置填充顏色
     CGContextSetFillColorWithColor(ctx, [[UIColor redColor] CGColor]);
     // 以觸碰點為圓心繪制一個圓形
     CGContextFillEllipseInRect(ctx, CGRectMake(curX - 10, curY - 10, 20, 20));
}
@end
 
參考:http://blog.sina.com.cn/s/blog_7b9d64af0101ae7q.html
     http://www.aiuxian.com/article/p-2244871.html
     http://www.jianshu.com/p/eb2c4bb4e3f1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM