標籤:因此 自訂 元素 poi 重新整理 空白 就會 自訂控制項 ext
1、layoutSubviews方法
- 1.1 根據蘋果官方協助文檔對layoutSubviews方法的解釋:
- 此方法用來重新定義子項目的位置和大小。當子類重寫此方法,用來實現UI元素的更精確布局。如果要讓布局重新重新整理,那麼就調用setNeedsLayout,即setNeedsLayout方法會預設用layoutSubViews方法。
- 1.2 很多時候系統會自動調用layoutSubviews方法:
- 1.初始化不會觸發layoutSubviews,但是如果設定了不為CGRectZero的frame的時候就會觸發。
- 2.addSubview會觸發layoutSubviews
- 3.設定view的Frame會觸發layoutSubviews,當然前提是frame的值設定前後發生了變化
- 4.滾動一個UIScrollView會觸發layoutSubviews
- 5.旋轉Screen會觸發父UIView上的layoutSubviews事件
- 6.改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件
- 1.3 註:setNeedsLayout方法並不會立即重新整理,立即重新整理需要調用layoutIfNeeded方法。
2、setNeedsDisplay方法
- 與setNeedsLayOut方法相似的方法是setNeedsDisplay方法。該方法在調用時,會自動調用drawRect方法。drawRect方法主要用來畫圖。
- 2.1 總結
- 所以,當需要重新整理布局時,用setNeedsLayOut方法;當需要重新繪畫時,調用setNeedsDisplay方法。
- 2.2 延伸:
- 當我們自訂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
iOS開發:setNeedsLayOut和setNeedsDisplay區別