2012-07-30 74 views
10

我正試圖用CALayers製作一個甜甜圈形狀。一個CALayer將成爲一個大圓圈,另一個將成爲一個位於其中心的小圓圈,掩蓋它。用另一個CALayer掩蓋CALayer

大圓顯示細膩,但每當我打電話circle.mask = circleMask;,則該視圖顯示爲空。

這裏是我的代碼:

AriDonut.h

#import <UIKit/UIKit.h> 

@interface AriDonut : UIView 
-(id)initWithRadius:(float)radius; 
@end 

AriDonut.m

#import "AriDonut.h" 
#import <QuartzCore/QuartzCore.h> 

@implementation AriDonut 

-(id)initWithRadius:(float)radius{ 
    self = [super initWithFrame:CGRectMake(0, 0, radius, radius)]; 
    if(self){ 

     //LARGE CIRCLE 
     CALayer *circle = [CALayer layer]; 
     circle.bounds = CGRectMake(0, 0, radius, radius); 
     circle.backgroundColor = [UIColor redColor].CGColor; 
     circle.cornerRadius = radius/2; 
     circle.position = CGPointMake(radius/2, radius/2); 

     //SMALL CIRLCE 
     CALayer *circleMask = [CALayer layer]; 
     circleMask.bounds = CGRectMake(0, 0, 10, 10); 
     circleMask.cornerRadius = radius/2; 
     circleMask.position = circle.position; 

     //circle.mask = circleMask; 

     [self.layer addSublayer:circle]; 

    } 

    return self; 
} 

我已經嘗試設置大圈的superlayer零這樣的:

CALayer *theSuper = circle.superlayer; 
theSuper = nil; 

但它沒有什麼不同。

我也試過圈的masksToBounds屬性設置爲YES和NO,但它並沒有發揮作用。

有什麼想法?

回答

13

事實上,作爲@大衛表示當前(的iOS 5.1)的CALayer面具不能顛倒,如果你想用他們做一個透明的孔圓形的簡單的CALayer這提出了一個問題。

你可以做一個甜甜圈是做一個圓形CALayer的backgroundColor透明,但給它一個borderColor和一個寬borderWidth。下面是鄧肯代碼:

CALayer *theDonut = [CALayer layer]; 
    theDonut.bounds = CGRectMake(0,0, radius, radius); 
    theDonut.cornerRadius = radius/2; 
    theDonut.backgroundColor = [UIColor clearColor].CGColor; 

    theDonut.borderWidth = radius/5; 
    theDonut.borderColor = [UIColor orangeColor].CGColor; 

    [self.layer addSublayer:theDonut]; 
4

這是掩碼圖層內容的alpha值用作掩碼。 (如果你將掩碼添加爲子圖層而不是將其用作掩碼,當用作掩碼時,子圖層覆蓋的所有內容都將可見,子圖層未覆蓋的所有內容在用作掩碼時都會隱藏。)

因爲你的小圈是完全透明的,一切都被屏蔽掉(隱藏)。如果你將它的backgroundColor設置爲任何完全不透明的顏色(只有alpha值用於蒙版),那麼它會讓這些像素通過。

請注意,這是你想要的相反。這隻會讓你看到「甜甜圈的洞」。沒有內置的方法來執行反轉蒙版相反,您必須以其他方式(如使用CAShapeLayer或使用drawInContext:)來繪製蒙版的內容。

1

我成功了CAShapeLayer掩蓋CALayer。要指定掩模CAShapeLayer的形狀,我使用了UIBezierPath

我張貼在我回答這個問題的代碼:How to Get the reverse path of a UIBezierPath。對於甜甜圈形狀,取消註釋該註釋行。

4

這是很容易使用UIBezierPath和CAShapeLayer作爲掩蔽層。代碼示例就像它在UIView子類中一樣書寫。

目的-C:

CGRect outerRect = self.bounds; 
CGFloat inset = 0.2 * outerRect.size.width; // adjust as necessary for more or less meaty donuts 
CGFloat innerDiameter = outerRect.size.width - 2.0 * inset; 
CGRect innerRect = CGRectMake(inset, inset, innerDiameter, innerDiameter); 
UIBezierPath *outerCircle = [UIBezierPath bezierPathWithRoundedRect:outerRect cornerRadius:outerRect.size.width * 0.5]; 
UIBezierPath *innerCircle = [UIBezierPath bezierPathWithRoundedRect:innerRect cornerRadius:innerRect.size.width * 0.5]; 
[outerCircle appendPath:innerCircle]; 
CAShapeLayer *maskLayer = [CAShapeLayer new]; 
maskLayer.fillRule = kCAFillRuleEvenOdd; // Going from the outside of the layer, each time a path is crossed, add one. Each time the count is odd, we are "inside" the path. 
maskLayer.path = outerCircle.CGPath; 
self.layer.mask = maskLayer; 

夫特:

let outerRect = self.bounds 
let inset: CGFloat = 0.2 * outerRect.width // adjust as necessary for more or less meaty donuts 
let innerDiameter = outerRect.width - 2.0 * inset 
let innerRect = CGRect(x: inset, y: inset, width: innerDiameter, height: innerDiameter) 
let outerCircle = UIBezierPath(roundedRect: outerRect, cornerRadius: outerRect.width * 0.5) 
let innerCircle = UIBezierPath(roundedRect: innerRect, cornerRadius: innerRect.width * 0.5) 
outerCircle.appendPath(innerCircle) 
let mask = CAShapeLayer() 
mask.fillRule = kCAFillRuleEvenOdd 
mask.path = outerCircle.CGPath 
self.layer.mask = mask