之前通過填充四周的方式去做 掃描框鹤啡。但是會填充不嚴(yán)實(shí)葫掉。
CGFloat bottomHeight = (kScreen_Height-self.heightAndWidth)/2;
CGFloat leftWidth = (kScreen_Width-self.heightAndWidth)/2;
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(ctx, 0, 0, 0, 0.5);
CGContextFillRect(ctx, CGRectMake(0, 0, kScreen_Width, bottomHeight));
CGContextStrokePath(ctx);
CGContextFillRect(ctx, CGRectMake(0,bottomHeight, leftWidth, self.heightAndWidth));
CGContextStrokePath(ctx);
CGContextFillRect(ctx, CGRectMake((kScreen_Width+self.heightAndWidth)/2, bottomHeight, leftWidth, self.heightAndWidth));
CGContextStrokePath(ctx);
CGContextFillRect(ctx, CGRectMake(0,(kScreen_Height+self.heightAndWidth)/2, kScreen_Width, bottomHeight));
CGContextStrokePath(ctx);
后來 發(fā)現(xiàn)了一個新方式:
CGFloat bottomHeight = (kScreen_Height-self.heightAndWidth)/2;
CGFloat leftWidth = (kScreen_Width-self.heightAndWidth)/2;
// 中間空心洞的區(qū)域
CGRect cutRect = CGRectMake(leftWidth,bottomHeight,self.heightAndWidth,self.heightAndWidth);
UIBezierPath *path = [UIBezierPath bezierPathWithRect:frame];
// 挖空心洞 顯示區(qū)域
UIBezierPath *cutRectPath = [UIBezierPath bezierPathWithRect:cutRect];
// 將circlePath添加到path上
[path appendPath:cutRectPath];
// 針對路徑愚铡,可有可無的
path.usesEvenOddFillRule = YES;
CAShapeLayer *fillLayer = [CAShapeLayer layer];
fillLayer.path = path.CGPath;
// 針對渲染的
fillLayer.fillRule = kCAFillRuleEvenOdd;
fillLayer.opacity = 0.3;//透明度
fillLayer.backgroundColor = [UIColor blackColor].CGColor;
[self.layer addSublayer:fillLayer];
效果如圖所示:
但是為什么這樣可以達(dá)到我們想要的效果呢拇颅?
通過探究發(fā)現(xiàn)娘摔,主要是
fillLayer.fillRule = kCAFillRuleEvenOdd;
這句代碼起到了作用
這句代碼有什么用呢菲语?
當(dāng)多邊形是自相交的惹盼,判斷一個點(diǎn)是否在多邊形內(nèi)庸汗,需要根據(jù)非零環(huán)繞數(shù)規(guī)則(kCAFillRuleNonZero)和奇-偶規(guī)則(kCAFillRuleEvenOdd)判斷。
(1)奇-偶規(guī)則(Odd-even Rule):從任意位置作一條射線手报,若與該射線相交的多邊形邊的數(shù)目為奇數(shù)蚯舱,則是多邊形內(nèi)部點(diǎn),否則是外部點(diǎn)掩蛤。
(2)非零環(huán)繞數(shù)規(guī)則(Nonzero Winding Number Rule):從任意位置作一條射線枉昏。當(dāng)沿射線方向移動時(shí),對在每個方向上穿過射線的邊計(jì)數(shù)揍鸟,每當(dāng)多邊形的邊從右到左穿過射線時(shí)兄裂,環(huán)繞數(shù)加1,從左到右時(shí),環(huán)繞數(shù)減1晰奖。處理完所有相關(guān)邊之后谈撒,若環(huán)繞數(shù)為非零,則為內(nèi)部點(diǎn)匾南,否則啃匿,是外部點(diǎn)。
舉??:
非零環(huán)繞數(shù)規(guī)則判斷點(diǎn)p是否在多邊形內(nèi)午衰,從點(diǎn)p向外做一條射線(可以任意方向)立宜,多邊形的邊從左到右經(jīng)過射線時(shí)環(huán)數(shù)減1,多邊形的邊從右往左經(jīng)過射線時(shí)環(huán)數(shù)加1臊岸,最后環(huán)數(shù)不為0橙数,即表示在多邊形內(nèi)部。
奇-偶規(guī)則 判斷點(diǎn)p是否在多邊形內(nèi)帅戒,從點(diǎn)p向外做一條射線(可以任意方向)灯帮,和兩條多邊形的邊相交。所以p點(diǎn)在多邊形外
所以最開始我們的代碼逻住。圖形的結(jié)構(gòu)是
p點(diǎn)在多邊形外钟哥,就不會被填充