首页 文章

CAShapeLayer上的CAGradientLayer SetMask崩溃应用程序

提问于
浏览
0

使用来自many great people的示例代码,我可以使用CAShapeLayer创建一个复杂的形状,并使用子类UIView表示没问题:

@implementation BMTestLogo

+ (Class)layerClass {
    return [CAShapeLayer class];
}


- (void)layoutSubviews {
    [self setUpPaths];
    [self setLayerProperties];
    //    [self attachAnimations];
}

- (void)setLayerProperties {
    CAShapeLayer *layer = (CAShapeLayer *)self.layer;
    //    _gradient = [CAGradientLayer layer];

    CGMutablePathRef combinedPath = CGPathCreateMutableCopy([[_UIBezierPathsArray objectAtIndex:0] CGPath]);

    for (UIBezierPath* path in _UIBezierPathsArray) {
        CGPathAddPath(combinedPath, NULL, path.CGPath);
    }

    layer.path = combinedPath;
    layer.fillColor = [UIColor clearColor].CGColor;
    layer.fillRule = kCAFillRuleEvenOdd;
}

这段代码效果很好,现在尝试在形状上添加CAGradientLayer和掩码,我一直在崩溃,特别是: QuartzCore CA::Layer::ensure_transaction_recursively(CA::Transaction*):

这是Gradient Code,请注意,这是从SO上的其他工作示例中获取的:

@implementation BMViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [_testLogo setNeedsDisplay];

    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.startPoint = CGPointMake(0.5,1.0);
    gradientLayer.endPoint = CGPointMake(0.5,0.0);
    gradientLayer.frame = CGRectMake(CGRectGetMinX(_testLogo.layer.bounds), CGRectGetMinY(_testLogo.layer.bounds), CGRectGetWidth(_testLogo.layer.bounds), CGRectGetHeight(_testLogo.layer.bounds));
    NSMutableArray *colors = [NSMutableArray array];
    for (int i = 0; i < 2; i++) {
        [colors addObject:(__bridge id)[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1].CGColor];
    }
    gradientLayer.colors = colors;
    NSNumber *stopOne = [NSNumber numberWithFloat:0.0];
    NSNumber *stopTwo  = [NSNumber numberWithFloat:1.0];
    NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, nil];
    gradientLayer.locations = locations;
    gradientLayer.needsDisplayOnBoundsChange = YES;
    [gradientLayer setMask:_testLogo.layer];
    [_testLogo.layer insertSublayer:gradientLayer atIndex:0];

    // Do any additional setup after loading the view, typically from a nib.
}

我试图调试和研究这个问题,UIColors的常见嫌疑人不是CGColors或(__bridge id)没有正确,我使用两个位置的渐变,只有2种颜色,而且我已经尝试了几十个不同版本:有或没有setNeeds显示,属性与局部声明,子类内的渐变层和out,所有在插入子层时仍然给我相同的崩溃 .

当我取出setMask:call时,它不会崩溃,只是用渐变填充整个框架 .

这似乎我只是遗漏了一些轻微或明显的东西 . 请注意,使用iOS 6和ARC - 希望继续使用CAShapeLayer和CAGradientLayer,因为它使动画更容易(这是最终目标) .

1 回答

  • 3

    以下代码在 ensure_transaction_recursively 中触发堆栈溢出 .

    [gradientLayer setMask:_testLogo.layer];
    [_testLogo.layer insertSublayer:gradientLayer atIndex:0];
    

    形状图层有一个渐变图层子视图,它有一个形状图层蒙版,它有一个渐变图层子视图......

    由于您的目标是使用由形状遮罩的渐变图层, BMTestLogo 应由 CAGradientLayer 支持,然后 CAShapeLayer 作为其蒙版 . 形状图层永远不应引用渐变图层 .

相关问题