2013-12-10 5 views
11

파이의 각 조각에 대해 CAShapeLayer를 사용하여 원형 차트를 그립니다. 한 파이 조각의 끝 각도가 인접 슬라이스의 시작 각도와 같을 때도 슬라이스 사이의 경계가 각을 이루는 경우 각 패이스 슬라이스 사이에 기본 배경색이 나타납니다.인접한 CAShapeLayer 앤티 앨리어싱 문제

http://i.stack.imgur.com/Qdu8d.png

나는 결과 파이 카트 여전히 부드러운 외모 때문에 여전히 안티 앨리어싱을 사용하는 동안 조각 사이에 약간의 간격을 제거하고 싶습니다

. 개념적으로 CALayer 전체에 앤티 엘리 어싱을 적용 할 수있는 방법이 있고 모든 파이 조각이 그려진 후 파이 조각 하위 레이어가있는 것 같습니다. 트릭을 수행 할 것입니다 ... 파이 조각은 서로에 대한 앤티 앨리어스가됩니다. 배경.

나는 이것에 대해 더 많은 정보를 찾는 데 어려움을 겪고있는 것처럼 많은 CALayer 속성으로 놀았습니다. 어떤 아이디어?

업데이트 : 내 대답보기.

답변

5

UPDATE : 롭의 대답은 꽤 좋은, 그러나 다른 안티 앨리어싱 문제의 가능한 결과. 나는 각 파이 슬라이스의 끝 각도를 따라 1pt 너비의 방사형 라인을 그려서 갭을 '채우는'결과를 보았습니다. 각 라인은 인접한 슬라이스와 같은 색이었습니다. 이 선은 원형 조각보다 낮은 z 색인에서 그려 지므로 아래에 있습니다.

The filler lines with no slices drawn.

을 그리고 여기에 최종 제품입니다 : 여기가 상단에 그려진 원형 조각없이 같이 무엇

Final result with lines underneath and slices on top.

8

아마도 파이 슬라이스 가장자리가 균열없이 정확히 만날 수는 없을 것입니다. 가장 간단한 해결책은 시도하지 않는 것입니다.

원형 조각을 가장자리에서 만나는 대신 겹치게하십시오. 전체 디스크와 같은 제 슬라이스 그린다

first slice

다음 첫 번째 슬라이스의 적절한 영역을 제외하고, 전체 디스크를 제 2 슬라이스 그린다

second slice

그 다음 그릴 첫 번째 두 슬라이스의 적절한 영역을 제외하고 전체 디스크로 세 번째 슬라이스 :

third slice

등등 :

fourth slicefifth slice

여기 내 코드입니다 :

#import "PieView.h" 

@implementation PieView { 
    NSMutableArray *slices; 
} 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code 
    } 
    return self; 
} 

- (void)layoutSubviews { 
    [super layoutSubviews]; 
    [self layoutSliceLayers]; 
} 

- (void)layoutSliceLayers { 
    if (slices == nil) { 
     [self createSlices]; 
    } 
    [slices enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
     [self layoutSliceLayer:obj index:idx]; 
    }]; 
} 

static const int kSliceCount = 5; 

- (void)createSlices { 
    slices = [NSMutableArray arrayWithCapacity:kSliceCount]; 
    for (int i = 0; i < kSliceCount; ++i) { 
     [slices addObject:[self newSliceLayerForIndex:i]]; 
    } 
} 

- (CAShapeLayer *)newSliceLayerForIndex:(int)i { 
    CAShapeLayer *layer = [CAShapeLayer layer]; 
    layer.fillColor = [UIColor colorWithWhite:(CGFloat)i/kSliceCount alpha:1].CGColor; 
    [self.layer addSublayer:layer]; 
    return layer; 
} 

- (void)layoutSliceLayer:(CAShapeLayer *)layer index:(int)index { 
    layer.position = [self center]; 
    layer.path = [self pathForSliceIndex:index].CGPath; 
} 

- (CGPoint)center { 
    CGRect bounds = self.bounds; 
    return CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds)); 
} 

- (UIBezierPath *)pathForSliceIndex:(int)i { 
    CGFloat radius = [self radius]; 
    CGFloat fudgeRadians = 5/radius; 
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero 
     radius:radius startAngle:2 * M_PI * i/kSliceCount 
     endAngle:2 * M_PI clockwise:YES]; 
    [path addLineToPoint:CGPointZero]; 
    [path closePath]; 
    return path; 
} 

- (CGFloat)radius { 
    CGSize size = self.bounds.size; 
    return 0.9 * MIN(size.width, size.height)/2; 
} 

@end 
+0

감사 응답, 롭에 대한 많은. 나는 한 때이 해결책을 시도해 보았고 어두운 바탕의 레이어가 배경으로 앤티 엘리 어싱 된 안티 앨리어싱 인공물을 보았습니다. 원형 차트 주위에 미묘한 짙은 색의 가장자리로 나타났습니다. 특히 밝은 색의 조각의 바깥 가장자리에서 두드러졌습니다. 필자가 설명한 방사형 필러 솔루션은 잘 작동하는 것 같습니다. – Aaron

+0

@Aaron 앤티 앨리어싱을 적용하면 효과적으로 별칭이 지정된 단색 모양 주위에 색상 + 알파 픽셀 링이 생깁니다. 동일한 외곽선을 가진 여러 도형에 대해 이렇게하면 효과적으로 에일 리어 앨리어스가 적용된 내부 영역은 잘 보이지만 앤티 앨리어스 영역에는 color (n) + alpha overlaying color (n-1) + alpha overlaying ... color (0) + 알파. 이것은 당신이보고있는 효과를 설명합니다. –