我试图绘制一个画圆通过使用 CAShapeLayer 和设置一个圆形路径上。但是,与使用 borderRadius 或直接在 CGContextRef 中绘制路径相比,此方法在呈现到屏幕时始终不太准确。
以下是这三种方法的结果:
请注意,第三个渲染得很差,特别是在顶部和底部的笔划内部。
I 有将 contentsScale
属性设置为 [UIScreen mainScreen].scale
。
这里是我的绘图代码为这三个圆。缺少什么,使 CAShapeLayer 绘制顺利?
@interface BCViewController ()
@end
@interface BCDrawingView : UIView
@end
@implementation BCDrawingView
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
self.backgroundColor = nil;
self.opaque = YES;
}
return self;
}
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
[[UIColor whiteColor] setFill];
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), NULL);
[[UIColor redColor] setStroke];
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 1);
[[UIBezierPath bezierPathWithOvalInRect:CGRectInset(self.bounds, 4, 4)] stroke];
}
@end
@interface BCShapeView : UIView
@end
@implementation BCShapeView
+ (Class)layerClass
{
return [CAShapeLayer class];
}
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
self.backgroundColor = nil;
CAShapeLayer *layer = (id)self.layer;
layer.lineWidth = 1;
layer.fillColor = NULL;
layer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(self.bounds, 4, 4)].CGPath;
layer.strokeColor = [UIColor redColor].CGColor;
layer.contentsScale = [UIScreen mainScreen].scale;
layer.shouldRasterize = NO;
}
return self;
}
@end
@implementation BCViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *borderView = [[UIView alloc] initWithFrame:CGRectMake(24, 104, 36, 36)];
borderView.layer.borderColor = [UIColor redColor].CGColor;
borderView.layer.borderWidth = 1;
borderView.layer.cornerRadius = 18;
[self.view addSubview:borderView];
BCDrawingView *drawingView = [[BCDrawingView alloc] initWithFrame:CGRectMake(20, 40, 44, 44)];
[self.view addSubview:drawingView];
BCShapeView *shapeView = [[BCShapeView alloc] initWithFrame:CGRectMake(20, 160, 44, 44)];
[self.view addSubview:shapeView];
UILabel *borderLabel = [UILabel new];
borderLabel.text = @"CALayer borderRadius";
[borderLabel sizeToFit];
borderLabel.center = CGPointMake(borderView.center.x + 26 + borderLabel.bounds.size.width/2.0, borderView.center.y);
[self.view addSubview:borderLabel];
UILabel *drawingLabel = [UILabel new];
drawingLabel.text = @"drawRect: UIBezierPath";
[drawingLabel sizeToFit];
drawingLabel.center = CGPointMake(drawingView.center.x + 26 + drawingLabel.bounds.size.width/2.0, drawingView.center.y);
[self.view addSubview:drawingLabel];
UILabel *shapeLabel = [UILabel new];
shapeLabel.text = @"CAShapeLayer UIBezierPath";
[shapeLabel sizeToFit];
shapeLabel.center = CGPointMake(shapeView.center.x + 26 + shapeLabel.bounds.size.width/2.0, shapeView.center.y);
[self.view addSubview:shapeLabel];
}
@end
编辑: 对于那些看不出区别的人,我在每个人上面画了一个圆圈,然后放大:
在这里,我用 drawRect:
画了一个红色的圆,然后在上面又用绿色的 drawRect:
画了一个相同的圆。注意有限的红色出血。这两个循环都是“平滑的”(与 cornerRadius
实现相同) :
在第二个示例中,您将看到这个问题。我曾经用红色的 CAShapeLayer
绘制过一次,然后在顶部用相同路径的 drawRect:
实现绘制过一次,但是是绿色的。请注意,您可以看到更多的不一致与更多的出血从下面的红色圆圈。它显然是以一种不同(甚至更糟)的方式绘制的。