? 最近開發(fā)的app增加了一個(gè)新手引導(dǎo)的需求。為了實(shí)現(xiàn)這個(gè)需求需要界面鏤空掉一部分〔宸穑現(xiàn)在就說(shuō)下iOS中實(shí)現(xiàn)界面鏤空的基本原理。
首先我們實(shí)現(xiàn)iOS中鏤空我們要使用到layer的mask屬性舆驶。那這個(gè)mask指的是什么啦拓轻?我們可以查閱下蘋果的文檔瞬铸。
意思就是layer不透明的部分才可以現(xiàn)實(shí)批幌,不透明的部分不可以顯示。這就是我們做鏤空效果的基礎(chǔ)嗓节。
?下一個(gè)問(wèn)題就是我們?cè)趺慈タ刂苐ayer的哪個(gè)部分顯示荧缘,哪個(gè)部分不顯示啦?我們就要用到貝塞爾曲線了拦宣。如果平時(shí)大家繪制過(guò)界面應(yīng)該都對(duì)貝塞爾曲線很熟悉截粗。下面我們就貼出iOS中鏤空的代碼信姓,大家看一看。
? UIWindow * window=[[[UIApplication sharedApplication] delegate] window];
?UIView *blackView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kwidth, kheight)];
?UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, kwidth, kheight)];
?[path appendPath:[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 100, 100) cornerRadius:0] ];
CAShapeLayer *layer = [CAShapeLayer layer]; ? ?
layer.path = path.CGPath;
[blackView.layer setMask:layer];
大家覺(jué)得這樣我們能實(shí)現(xiàn)鏤空效果了嗎绸罗?
答案是不能财破。但是為什么啦?其實(shí)第一次實(shí)現(xiàn)這個(gè)效果我就是這樣寫的代碼从诲。但是發(fā)現(xiàn)并沒(méi)有效果。后面查閱資料才知道為什么靡羡。其實(shí)就是繪圖的填充規(guī)則系洛。iOS的填充規(guī)則其實(shí)有兩種。一種叫非零環(huán)繞數(shù)原則略步,一種叫奇偶原則描扯。UIBezierPath有一個(gè)屬性叫做usesEvenOddFillRule,這個(gè)屬性是個(gè)Bool值趟薄。意思是是否使用奇偶原則绽诚。 默認(rèn)是NO。我們上面的代碼不成功的原因就是因?yàn)樘畛湟?guī)則的問(wèn)題杭煎。這兩個(gè)填充規(guī)則我也是在另外一篇文章中看到的恩够。寫的很詳細(xì)。大家一定要看了這篇文章繪圖的填充規(guī)則羡铲,再看下面的內(nèi)容蜂桶。不然也不能理解代碼。
文章詳細(xì)的說(shuō)明了界面哪些地方應(yīng)該繪制也切。哪些地方不能繪制扑媚。寫的很詳細(xì)±资眩看了之后我們就應(yīng)該知道上面代碼不能實(shí)現(xiàn)鏤空效果的原因了疆股。就是UIBezierPath的填充規(guī)則是默認(rèn)非零環(huán)繞原則。所以我們上面那樣的寫法還是繪制了frame的所有地方〉够保現(xiàn)在我們有兩種方法可以修改上面的代碼打到鏤空效果旬痹。第一種是
?[path appendPath:[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 100, 100)?cornerRadius:0]? bezierPathByReversingPath]];
關(guān)鍵就是bezierPathByReversingPath這個(gè)方法。這個(gè)方法其實(shí)就是將貝塞爾曲線繪制的起點(diǎn)和終點(diǎn)交換了位置讨越。這樣就可以滿足非零環(huán)繞原則唱凯,達(dá)到后面矩形區(qū)域里面的內(nèi)容不繪制了。
還是一種就是將usesEvenOddFillRule直接設(shè)為YES谎痢。就是我們奇偶原則磕昼。兩個(gè)path重疊的部分不進(jìn)行繪制。我們同樣也可以實(shí)現(xiàn)鏤空效果了〗谠常現(xiàn)在我們想要的鏤空效果就完成了票从。是不是明白了原理也不是很難漫雕。
學(xué)習(xí)代碼我們要多看官方文檔。多查閱資料峰鄙。這樣才能進(jìn)步的更快浸间。