如何将CALayer子类化为另一个CALayer掩码?

Ric*_*aez 5 core-animation core-graphics objective-c uiview ios

我试图将子类CALayer用作另一层的掩码.

我想用我的CALayer子类来代替的CAGradientLayer,并用它的灰度掩模作为解释在这里.

但是我希望使用一个CALayer使用内部CGGradient进行绘制的自定义,因为这应该产生比CAGradientLayer(见这里)更平滑的结果.我不关心性能,我想要更好的渐变质量.

我正在按照这个例子来创建我CGGradient并将它存储在CALayer..然而,我无法得到掩码.

我不知道放在哪里抽奖代码:CALayerdisplay,也不drawInContext:(CGContextRef)ctx也不drawInContext:(CGContextRef)ctx似乎被调用时,它被用作面膜.

跟我一起玩,因为我是CoreAnimation的新手.那么,如何解决这个问题,以便我的CALayer子类可以替代它,CAGradientLayer但是使用CGGradient


我目前的代码在这里:

@interface CANiceGradientLayer : CALayer

@property (nonatomic) CGGradientRef gradient;
@property (atomic) CGPoint startPoint;
@property (atomic) CGPoint endPoint;

@end

@implementation CANiceGradientLayer

- (instancetype)initWithGradientRef:(CGGradientRef)gradient startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint
{
    if ( !(self = [super init]) )
    {
        return nil;
    }

    self.gradient = CGGradientRetain(gradient);
    self.startPoint = startPoint;
    self.endPoint = endPoint;

    return self;
}

- (void)dealloc
{
    CGGradientRelease(self.gradient);
}

- (void)display
{
    NSLog(@"display");
}

- (void)drawInContext:(CGContextRef)ctx
{
    NSLog(@"drawInContext:");
    CGContextDrawLinearGradient(ctx, self.gradient, self.startPoint, self.endPoint, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);;
}

- (void)renderInContext:(CGContextRef)ctx
{
    NSLog(@"renderInContext:");
}

@end
Run Code Online (Sandbox Code Playgroud)

以下是我创建它的方法:

size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1.0, 1.0, 1.0, 1.0,  // Start color
                          1.0, 1.0, 1.0, 0.0 }; // End color

CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);


self.collectionViewTickerMaskLayer = [[CANiceGradientLayer alloc] initWithGradientRef:gradient startPoint:CGPointZero endPoint:CGPointZero];


self.collectionViewTickerMaskLayer.anchorPoint = CGPointZero;
view.layer.mask = self.collectionViewTickerMaskLayer;
Run Code Online (Sandbox Code Playgroud)

如果我用一个CAGradientLayer代替,它工作正常(但渐变看起来很糟糕).

Ale*_*ski 2

在将图层子类设置为蒙版之前调用-setNeedsDisplay它,您只需要覆盖-drawInContext:CALayer类。这将帮助您获取要调用的方法(CALayer-drawInContext:使用其默认实现调用-displayafter -setNeedsDisplay)。您可能还需要设置图层的框架:

self.collectionViewTickerMaskLayer.frame = view.layer.bounds;
self.collectionViewTickerMaskLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
Run Code Online (Sandbox Code Playgroud)

这段代码有逻辑问题。您使用的端点是 CGPointZero,因此即使调用这些方法,也不会绘制任何渐变来遮盖您的图层。