2013-07-29 62 views
0

manygreatpeople使用示例代碼中,我能夠讓使用CAShapeLayer複雜的形狀和現在,使用一個子類的UIView沒有問題:CAGradientLayer SetMask上CAShapeLayer崩潰的應用程序

@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*):

這裏是漸變的代碼,請注意,這是從其他工作實例採取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:call時,它不會崩潰,只是用漸變填充整個框架。

這看起來好像我只是缺少一些小的或明顯的東西。請注意,使用iOS 6和ARC--希望繼續使用CAShapeLayer和CAGradientLayer,因爲它使動畫變得更容易(這是最終目標)。

回答

3

以下代碼觸發ensure_transaction_recursively中的堆棧溢出。

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

形狀層,其具有具有梯度層子視圖的形狀圖層蒙版漸變層子視圖...

因爲你的目標是有一個由形狀屏蔽的梯度層, BMTestLogo應該由CAGradientLayer支持,然後CAShapeLayer作爲其掩碼。形狀圖層不應該引用漸變圖層。

+0

恩,布賴恩,那當然有訣竅!我應該使用intuiton,因爲它會說「RECURSIVELY!」 - 你有時間澄清一些事情嗎? 1)看這個答:http://stackoverflow.com/questions/4733966/applying-a-gradient-to-cashapelayer - 爲什麼這個工作通過設置漸變層的形狀的面具,然後添加層以及?此外,我的目標是重新創建此:https://www.dropbox.com/sh/t0yfvxakw9oto69/Ji0bYznFVT - 我可以使用Paintcode,我的計劃是創建16 CAGradientLayer的16 BezierPaths作爲CAShapeLayer – Max

+0

這將需要16 sepearte UIView作爲CAGradientLayers支持,每個都有根據貝塞爾路徑的特定漸變並應用相同的邏輯? – Max

+1

在該解決方案中,'v.layer!= gradientMask'。他們所做的是創建一個新的形狀圖層,將其設置爲新漸變圖層的蒙版,並將漸變圖層插入視圖的圖層(大概只是一個'CALayer')。 –