【发布时间】:2014-07-13 15:33:23
【问题描述】:
我正在尝试继承 CALayer 以用作另一层的蒙版。
我想使用我的CALayer 子类代替CAGradientLayer,并将其用于渐变蒙版,如here 所述。
但是,我希望使用自定义CALayer 来代替使用内部CGGradient 进行绘图,因为这应该会产生比CAGradientLayer (see here) 更平滑的结果。我不关心性能,我想要更好的渐变质量。
我正在关注 this example 创建我的 CGGradient 并将其存储在 CALayer.. 但是,我无法绘制蒙版。
我不知道把draw code放在哪里:CALayer的display也不是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
这就是我的创建方式:
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;
如果我改用CAGradientLayer,它可以正常工作(但渐变看起来很糟糕)。
【问题讨论】:
-
只是猜测:继承自 CAShapeLayer 而不是 CALayer ? - 我认为您必须将 CAShapeLayers 用于 mask 属性(尽管它接受任何 CALayer 对象的事件)...
-
@Cabus OP 说使用 CAGradientLayer 也可以,所以我认为这不是问题。
-
我看到你正在覆盖
renderInContext:。这可能是问题吗?请尝试调用超级实现或将其注释掉,看看是否有变化。
标签: ios objective-c uiview core-graphics core-animation