iphone - CAShapeLayer 上的 CAGradientLayer SetMask 使应用程序崩溃

标签 iphone ios core-graphics cashapelayer cagradientlayer

使用来自 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 和 mask ,但我一直遇到崩溃,特别是: QuartzCore CA::Layer::ensure_transaction_recursively(CA::Transaction*):

这是梯度代码,请注意,这是从 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 显示,属性与本地声明,子类内部和外部的渐变层,在插入子层时仍然给我同样的崩溃。

当我取出 setMask: 调用时,它不会崩溃,只是用渐变填充整个帧。

这似乎我只是遗漏了一些次要的或明显的东西。请注意,使用 iOS 6 和 ARC - 希望继续使用 CAShapeLayer 和 CAGradientLayer,因为它可以更轻松地制作动画(这是最终目标)。

最佳答案

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

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

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

因为你的目标是有一个被形状遮盖的渐变层,BMTestLogo 应该由 CAGradientLayer 支持,然后有一个 CAShapeLayer 作为掩码。形状层不应引用渐变层。

关于iphone - CAShapeLayer 上的 CAGradientLayer SetMask 使应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17930881/

相关文章:

ios - CIDetector 在面部特征上给出了错误的位置

iphone - UIKit、Core Graphics、Core Animation、OpenGL 的哪些部分允许在非主线程上使用?

ios - 将 Objective-C 代码转换为 Swift : okay to omit release calls?

iphone - 将 PNG 图像绘制到图形上下文中以进行混合模式操作

ios - 如何逐渐降低 UIButton 的不透明度?

ios - ios中的 ScrollView 控件

objective-c - 为什么 Objective-C block 在不将其复制到堆中的情况下仍然有效?

iphone - 如何在cocos2d中设置CCLabelTTF的背景颜色

iphone - 使用 Objective-C 进行 USB 编程

ios - 自定义表格 View 单元格作为字符串