iOS/OC: Quartz2D畫圓角矩形時的線寬不一致問題->Quartz2D抗鋸齒機制問題

版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。

圓角矩形一般直接AddArc...或者用BezierPath,

+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;
+(instancetype)ImageFromFrame:(CGSize)size
                  BorderColor:(UIColor *)color
                 BorderRadius:(CGFloat)radius
                  BorderWidth:(CGFloat)width
{
    CGFloat x = size.width;
    CGFloat y = size.height;
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBFillColor (context,  1.0, 1.0, 1.0, 1.0);//設置填充顏色(白色)
    CGContextSetLineWidth(context, width);//線的寬度
    CGContextSetStrokeColorWithColor(context, color.CGColor);//線框顏色
//方法1
    //    CGPathRef clippath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0,0, x, y)cornerRadius:radius].CGPath;
    //    CGContextAddPath(context, clippath);
//方法2
    CGContextMoveToPoint(context, x, y-radius);  // 開始坐標右邊開始
    CGContextAddArcToPoint(context, x, y, x-radius, y, radius);  // 右下角角度
    CGContextAddLineToPoint(context, radius, y);
    CGContextAddArcToPoint(context, 0, y, 0, y-radius, radius); // 左下角角度
    CGContextAddLineToPoint(context, 0, radius);
    CGContextAddArcToPoint(context, 0, 0, radius, 0, radius); // 左上角
    CGContextAddLineToPoint(context, x-radius, 0);
    CGContextAddArcToPoint(context, x, 0, x, radius, radius); // 右上角
    CGContextClosePath(context);

    CGContextDrawPath(context, kCGPathFillStroke); 
    UIImage *newImage=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

這個方法看上去沒什么問題,的確是按背景大小沿著路徑畫的,但是調(diào)試一下就會發(fā)現(xiàn),當背景的clipsToBounds = YES時,畫出來的圓角矩形圓角處的線寬和直線的線寬是不一致的,效果非常詭異.感覺邊緣都被截去了,也就是說 畫出的圓角矩形超出了背景大小

9E7D47FF-40E5-4465-ACD7-0BC5F6983F4B.png

找了好久,后發(fā)現(xiàn)一篇有用的博文

跟Quartz2D的繪制時的抗鋸齒機制有關
http://my.oschina.net/lych0317/blog/126215
具體原理看博文,不過里面的代碼也是有問題的.

正確完美的解決方案如下:

路徑及半徑要往里扣除線寬的一半 !!!!

UIImage的分類

#import <UIKit/UIKit.h>
@interface UIImage (JLImage)
/**
 繪制圓角矩形
 
 @param size 畫布大小
 @param borderColor 邊緣顏色
 @param borderRadius 圓角半徑
 @param borderWidth 線寬
 @param margin 上下左右間距
 */
+ (instancetype)roundRectImageWithFrame:(CGSize)size
                            borderColor:(UIColor *)borderColor
                           borderRadius:(CGFloat)borderRadius
                            borderWidth:(CGFloat)borderWidth
                                 margin:(CGFloat)margin;
@end
#import "UIImage+JLImage.h"
@implementation UIImage (JLImage)
+ (instancetype)roundRectImageWithFrame:(CGSize)size
                            borderColor:(UIColor *)borderColor
                           borderRadius:(CGFloat)borderRadius
                            borderWidth:(CGFloat)borderWidth
                                 margin:(CGFloat)margin
{
       CGFloat x = size.width;
    CGFloat y = size.height;
    CGFloat radius = borderRadius - margin;
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBFillColor (context,  1.0, 1.0, 1.0, 1.0);//設置填充顏色(白色)
    CGContextSetLineWidth(context, borderWidth);//線的寬度
    CGContextSetStrokeColorWithColor(context, borderColor.CGColor);//線框顏色
    //繪制path 方法1
    CGPathRef clippath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(borderWidth/2 +margin,borderWidth/2 +margin, x - borderWidth - margin*2, y - borderWidth - margin*2)cornerRadius:radius].CGPath;
    CGContextAddPath(context, clippath);
    //繪制path 方法2
//    CGContextMoveToPoint(context, x-borderWidth/2 -margin, y-radius - margin);  // 開始坐標右邊開始
//    CGContextAddArcToPoint(context, x-borderWidth/2 -margin, y-borderWidth/2 - margin, x-radius -margin, y-borderWidth/2-margin, radius - borderWidth/2);  // 右下角角度
//    CGContextAddLineToPoint(context, radius+margin, y-borderWidth/2-margin);
//    CGContextAddArcToPoint(context,  borderWidth/2+margin, y-borderWidth/2-margin, borderWidth/2+margin, y-radius-margin, radius-borderWidth/2); // 左下角角度
//    CGContextAddLineToPoint(context, borderWidth/2 +margin, radius+margin);
//    CGContextAddArcToPoint(context, borderWidth/2+margin, borderWidth/2+margin, radius+margin, borderWidth/2+margin, radius-borderWidth/2); // 左上角
//    CGContextAddLineToPoint(context, x-radius-borderWidth/2-margin, borderWidth/2 +margin);
//    CGContextAddArcToPoint(context, x-borderWidth/2- margin, borderWidth/2 +margin, x-borderWidth/2 - margin, radius +margin, radius-borderWidth/2); // 右上角
//    CGContextClosePath(context);
    //填充
    CGContextDrawPath(context, kCGPathFillStroke); 
    UIImage *newImage=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newImage;
}
@end

方法1和方法2效果是一樣的

A2AC47A0-C9B5-48A8-86B9-8C498DC1C2C1.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容