CAShapeLayer를 사용하고 그 위에 원형 경로를 설정하여 획이있는 원을 그리려고합니다. 그러나이 방법은 borderRadius를 사용하거나 CGContextRef에서 직접 경로를 그리는 것보다 화면에 렌더링 할 때 일관성이 떨어집니다.
다음은 세 가지 방법 모두의 결과입니다.
세 번째는 특히 상단과 하단의 획 내부에서 제대로 렌더링되지 않습니다.
나는 한 설정된 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:
, 동일한 경로를 구현 하여 다시 맨 위에 녹색 으로 그렸습니다 . 아래의 빨간색 원에서 더 많은 블리드로 인해 훨씬 더 많은 불일치를 볼 수 있습니다. 그것은 분명히 다른 (그리고 더 나쁜) 방식으로 그려지고 있습니다.