Mac OS X下實現矩形部分圓角

weixin_34050427發表於2018-09-27

問題

在進行今天的內容之前,首先我想問一個問題:下圖中,藍色選擇框與紅色選擇框除顏色、大小外有何不同?(我會在後文揭曉答案)

13291912-860ccc698b6ae2da.png
圖1

目標

本文今天要討論的是:在Mac OS X下,如何實現矩形的部分圓角。

比如這樣:

13291912-e29721d29ea6969f.png
圖2

或者這樣:

13291912-2a6536fd8c68f4ed.png
圖3

解決方案

要想實現上圖樣式,有兩種解決方案。

方案1:蠢萌描點法

蠢萌描點法實現圖2的原理圖如下:

13291912-1c9508bac645d70f.png
蠢萌描點法原理圖

如上圖所示,首先確定整個矩形的的幾個特殊點,然後通過CGContextAddLineToPoint來實現繪製。

核心程式碼

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    
    CGMutablePathRef path = CGPathCreateMutable();
    CGContextRef cr = [[NSGraphicsContext currentContext] graphicsPort];
    
    CGContextAddPath(cr, path);
    //為了照顧視力不好的童鞋,我將圖2的座標擴大了10倍。
    //順時針將座標填充入引數即可
    CGContextMoveToPoint(cr, 0, 0);
    CGContextAddLineToPoint(cr, 0, 150);
    CGContextAddArcToPoint(cr,
                           0, 180,
                           30, 180,
                           30);
    CGContextAddLineToPoint(cr, 270, 180);
    CGContextAddArcToPoint(cr,
                           300, 180,
                           300, 150,
                           30);
    CGContextAddLineToPoint(cr, 300, 0);
    CGContextAddLineToPoint(cr, 0, 0);
    
    CGContextSetRGBFillColor(cr, 255.0/255.0, 0.0/255.0, 0.0/255.0, 1);
    CGContextDrawPath(cr, kCGPathFill);
    
    CGPathRelease(path);
}

效果

13291912-d46a6fb49bc4189e.png
蠢萌描點法效果

根據寫程式碼來看,蠢萌描點法手法過於粗糙,我不會告訴你在實際專案中座標花了我大半天時間去計算。(真的是半天!)
So....方案二騰空出世!

方案二:猥瑣遮掩法

猥瑣遮蓋法實現圖3的原理如下:

13291912-0aeb328f58fefb45.png
猥瑣遮蓋法原理圖

看上去極易操作,程式碼極易簡潔,符合我一貫的程式碼美學風格,完美,所以接下來.....我們繼續算座標!(狗頭)

13291912-988aa7bb7285b2c5.png
image.png

核心程式碼

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    NSRect originalRect = NSMakeRect(0, 0, 300, 180);
    NSRect coverRect = NSMakeRect(0, 150, 300, 30);
    
    NSColor *red = [NSColor redColor];
    [red setFill];
    
    //圓角矩形
    NSBezierPath *originalPath = [NSBezierPath bezierPathWithRoundedRect:originalRect xRadius:30 yRadius:30];
    [originalPath fill];
    
    //遮掩矩形
    NSBezierPath *coverPath = [NSBezierPath bezierPathWithRect:coverRect];
    [coverPath fill];
}

效果圖

13291912-fb724b863c2c61e2.png
猥瑣遮掩法實現圖2效果圖

結語

那麼圖1中,兩個選擇框究竟有什麼區別呢,如圖所示:

13291912-d4dba1e762dbd486.png
不同

搞了這麼多花裡胡哨,終於滿足了美工姐姐的奇葩需求,完美!
(需要專案程式碼的同學,請私聊我。)

相關文章