2011-12-13 111 views
2

我建立一個UIBezierPath如下:CAShapeLayer描繪軌跡奇怪

UIBezierPath *path = [UIBezierPath bezierPath]; 
CGFloat yOrigin = 2; 
for (int i = 0; i < lines; ++i) { 
    [path moveToPoint:CGPointMake(0, yOrigin)]; 
    [path addLineToPoint:CGPointMake(width, yOrigin)]; 
    yOrigin += distance; 
} 
[path closePath]; 

然後我把它放在一個CAShapeLayer:

CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init]; 
[shapeLayer setFrame:aFrame]; 
[shapeLayer setPath:[bezierPath CGPath]]; 
[shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]]; 
[shapeLayer setMasksToBounds:YES]; 

然而,當添加到我的滾動視圖,這裏是結果:

Path Image

它爲什麼要這樣做呢?前四條線幾乎是灰色的!它看起來像一個別名問題,但路徑非常簡單。

回答

5

是的,這是一個反鋸齒問題。

您使用的路徑寬度爲1磅。在上面的例子中,CAShapeLayer的上面三個實例被精確地定位在整個點值的中心,例如。 5.0,其中較低的實例位於兩個整點之間,例如。 14.5。

當系統將您的圖層渲染爲屏幕像素時,它會對前三行進行抗鋸齒,以50%的透明度繪製兩個觸摸像素。下線完美地坐在一個像素上,因此被完全繪製成黑色。

我希望有一點ASCII藝術有助於理解。

pt   upper lines       lower line 
5.0|---------          ------------------------------- 
    | pixel -------------------------------------- perfectly aligned center 5.5 
6.0|--------- line between pixels centered on 6.0 ------------------------------- 
    | pixel -------------------------------------- 
7.0|--------- 
+0

這當然是這樣,但爲什麼我的路徑代碼實際上這樣做?假設「距離」是12.0。它應該落在整個點上。 – DexterW

0

我得到了同樣的情況:垂直和水平黑線變成灰色。

它看起來像像素上的UiView'snap'座標,而不是CALayer。

我對這個問題的解決方案是在coodinates上加0.5。

CGRect bounds_on_pixels(const CGRect& bounds) { 

    const float f = 0.5f; 
    return CGRectMake(bounds.origin.x+f, bounds.origin.y+f, bounds.size.width-1.f, bounds.size.height-1.f); 
} 

注意:-1.f在尺寸上是兼性的。用CAShapeLayer使用和UIBezierPath

CAShapeLayer* shape_layer = [CAShapeLayer layer]; 
// initialize shape_layer... 
shape_layer.path = 
[ 
UIBezierPath bezierPathWithRoundedRect:bounds_on_pixels(self.view.bounds) 
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight 
cornerRadii:CGSizeMake(10.0, 10.0) 
].CGPath; 
// add shape_layer: [self.view.layer insertSublayer:shape_layer atIndex:0]; 

@tonklon的

例如:THX爲理念!