我正在尝试将CALayer
子类化为另一层的掩码。
我想使用我的CALayer
子类代替CAGradientLayer
,并将其用作渐变蒙版,如here所述。
但是,我希望使用使用内部CALayer
进行绘制的自定义CGGradient
,因为这会产生比CAGradientLayer
(see here)更平滑的结果。我不关心性能,我想要更好的渐变质量。
我正在关注this example创建我的CGGradient
并将其存储在CALayer
上。但是,我无法绘制掩码。
我不知道在哪里放置绘图代码:CALayer
的{{1}},display
和drawInContext:(CGContextRef)ctx
似乎在用作面具时被调用
请耐心等待我,因为我是CoreAnimation的新手。那么,如何解决这个问题,以便我的drawInContext:(CGContextRef)ctx
子类可以替代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
如果我使用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;
代替,它可以正常工作(但渐变看起来很糟糕)。
答案 0 :(得分:2)
在将图层子类设置为蒙版之前调用图层子类上的-setNeedsDisplay
,并且您只需要覆盖-drawInContext:
子类的CALayer
。这将帮助您获取要调用的方法(CALayer使用-drawInContext:
之后调用的-display
默认实现来调用-setNeedsDisplay
。您可能还需要设置图层的框架:
self.collectionViewTickerMaskLayer.frame = view.layer.bounds;
self.collectionViewTickerMaskLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
此代码中存在逻辑问题。您使用的是CGPointZero端点,因此即使调用这些方法,也不会绘制任何渐变来掩盖您的图层。