自定义View相关
實(shí)現(xiàn)自定義View的關(guān)鍵是重載UIView的drawRect: 方法,因?yàn)橹饕峭ㄟ^重載這個(gè)方法,來改變view的外觀。
例如:
?
- (void)drawRect:(CGRect)rect{
// 繪圖
CGRect bounds = [self bounds];
// Where is its center?
CGPoint center;
center.x = bounds.origin.x + bounds.size.width / 2.0;
center.y = bounds.origin.y + bounds.size.height / 2.0;
// From the center how far out to a corner?
float maxRadius = hypot(bounds.size.width, bounds.size.height) / 2.0;
// Get the context being drawn upon
CGContextRef context = UIGraphicsGetCurrentContext();
// All lines will be drawn 10 points wide
CGContextSetLineWidth(context, 10);
// Set the stroke color to light gray
[[UIColor lightGrayColor] setStroke];
// Draw concentric circles from the outside in
for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20)
{
CGContextAddArc(context, center.x, center.y,
currentRadius, 0.0, M_PI * 2.0, YES);
CGContextStrokePath(context);
}
// 繪文字
NSString *text = @"Hello,World!";
// Get a font to draw it in
UIFont *font = [UIFont boldSystemFontOfSize:28];
// Where am I going to draw it?
CGRect textRect;
textRect.size = [text sizeWithFont:font];
textRect.origin.x = center.x - textRect.size.width / 2.0;
textRect.origin.y = center.y - textRect.size.height / 2.0;
// Set the fill color of the current context to black
[[UIColor blackColor] setFill];
// Set the shadow to be offset 4 points right, 3 points down,
// dark gray and with a blur radius of 2 points
CGSize offset = CGSizeMake(4, 3);
CGColorRef color = [[UIColor darkGrayColor] CGColor];
CGContextSetShadowWithColor(context, offset, 2.0, color);
// Draw the string
[text drawInRect:textRect
withFont:font]; }
再說明一下重繪,重繪操作仍然在drawRect方法中完成,但是蘋果不建議直接調(diào)用drawRect方法,當(dāng)然如果你強(qiáng)直直接調(diào)用此方法,當(dāng)然是沒有效果的。
蘋果要求我們調(diào)用UIView類中的setNeedsDisplay方法,則程序會(huì)自動(dòng)調(diào)用drawRect方法進(jìn)行重繪。(調(diào)用setNeedsDisplay會(huì)自動(dòng)調(diào)用drawRect)
在UIView中,重寫drawRect: (CGRect) aRect方法,可以自己定義想要畫的圖案.且此方法一般情況下只會(huì)畫一次.也就是說這個(gè)drawRect方法一般情況下只會(huì)被掉用一次.?當(dāng)某些情況下想要手動(dòng)重畫這個(gè)View,只需要掉用[self setNeedsDisplay]方法即可.
drawRect調(diào)是在Controller->loadView, Controller->viewDidLoad 兩方法之后調(diào)用的.所以不用擔(dān)心在控制器中,這些View的drawRect就開始畫了.這樣可以在控制器中設(shè)置一些值給View(如果這些View draw的時(shí)候需要用到某些變量值).
1.如果在UIView初始化時(shí)沒有設(shè)置rect大小,將直接導(dǎo)致drawRect不被自動(dòng)調(diào)用。2.該方法在調(diào)用sizeThatFits后被調(diào)用,所以可以先調(diào)用sizeToFit計(jì)算出size。然后系統(tǒng)自動(dòng)調(diào)用drawRect:方法。
3.通過設(shè)置contentMode屬性值為UIViewContentModeRedraw。那么將在每次設(shè)置或更改frame的時(shí)候自動(dòng)調(diào)用drawRect:。
4.直接調(diào)用setNeedsDisplay,或者setNeedsDisplayInRect:觸發(fā)drawRect:,但是有個(gè)前提條件是rect不能為0.
以上1,2推薦;而3,4不提倡
1、若使用UIView繪圖,只能在drawRect:方法中獲取相應(yīng)的contextRef并繪圖。如果在其他方法中獲取將獲取到一個(gè)invalidate的ref并且不能用于畫圖。drawRect:方法不能手動(dòng)顯示調(diào)用,必須通過調(diào)用setNeedsDisplay 或者 setNeedsDisplayInRect ,讓系統(tǒng)自動(dòng)調(diào)該方法。
2、若使用calayer繪圖,只能在drawInContext: 中(類似于drawRect)繪制,或者在delegate中的相應(yīng)方法繪制。同樣也是調(diào)用setNeedDisplay等間接調(diào)用以上方法。
3、若要實(shí)時(shí)畫圖,不能使用gestureRecognizer,只能使用touchbegan等方法來掉用setNeedsDisplay實(shí)時(shí)刷新屏幕
附高人對UIView的drawRect: 和 - (void)setNeedsDisplay 的一些理解
在UIView中,
1、自定義畫圖,類似android的onDraw()
- (void)drawRect:(CGRect)rect;
?is invoked automaticall,never call it directly!!2、刷新視圖,類似android的invalidate()
- (void)setNeedsDisplay;
When a view needs to be redrawn,use:?
3、在非主線程中調(diào)用,需使用如下方法:
????? - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait
?? ?? - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
4、setNeedsDisplay是不阻塞的,
?? ? 需要自己制造阻塞,
?? ? setNeedsDisplay我理解就是告訴系統(tǒng),等會(huì)幫哥把這塊重新畫一下。
???? 系統(tǒng)就知道了,等系統(tǒng)有空了,他就一起畫了,
?? ? 如果想立即畫出來,可能要用setNeedsLayout,
?? ? 或者不用drawInRect系列的方式,直接改view.image或者文字,加動(dòng)畫等方式實(shí)現(xiàn)吧。
5、setNeedsDisplay和layoutSubViews
???? 首先兩個(gè)方法都是異步執(zhí)行的。而setNeedsDisplay會(huì)調(diào)用自動(dòng)調(diào)用drawRect方法,這樣可以拿到UIGraphicsGetCurrentContext,就可以畫畫了。而setNeedsLayout會(huì)默認(rèn)調(diào)? 用layoutSubViews,就可以處理子視圖中的一些數(shù)據(jù)。
綜上所訴,setNeedsDisplay方便繪圖,而layoutSubViews方便出來數(shù)據(jù)。
轉(zhuǎn)載于:https://www.cnblogs.com/ranger-jlu/p/3957096.html
與50位技術(shù)專家面對面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
- 上一篇: 操作系统之内存管理:4、基本地址变换机构
- 下一篇: 计组之存储系统:4、双口RAM和多模块存