2013-03-26 30 views
7

我使用這個代碼到一個層施加到一個UIView:應用一個CAShapeLayer面具一個UIView

mask = [[CAShapeLayer alloc] init]; 
mask.frame = baseView.layer.bounds; 
CGRect biggerRect = CGRectMake(mask.frame.origin.x, mask.frame.origin.y, mask.frame.size.width, mask.frame.size.height); 
CGRect smallerRect = CGRectMake(0.0f, 0.0f, 0.0f, 0.0f); 

UIBezierPath *maskPath = [UIBezierPath bezierPath]; 
[maskPath moveToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMinY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMaxY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(biggerRect), CGRectGetMaxY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(biggerRect), CGRectGetMinY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMinY(biggerRect))]; 

[maskPath moveToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMinY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMaxY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(smallerRect), CGRectGetMaxY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(smallerRect), CGRectGetMinY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMinY(smallerRect))]; 

mask.path = maskPath.CGPath; 
[mask setFillRule:kCAFillRuleEvenOdd]; 
mask.fillColor = [[UIColor blackColor] CGColor]; 
baseView.layer.mask = mask; 

因爲我希望削減改變矩形,我wonderning如果有一個快速的方法來改變面具的大小,而不是將其從UIview中移除並重新應用其不同尺寸:

eg

[mask removeFromSuperlayer]; 

和...

mask = [[CAShapeLayer alloc] init]; 
mask.frame = baseView.layer.bounds; 
CGRect biggerRect = CGRectMake(mask.frame.origin.x, mask.frame.origin.y, mask.frame.size.width, mask.frame.size.height); 
CGRect smallerRect = CGRectMake(0.0f, 100.0f, 200.0f, 200.0f); 

UIBezierPath *maskPath = [UIBezierPath bezierPath]; 
[maskPath moveToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMinY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMaxY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(biggerRect), CGRectGetMaxY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(biggerRect), CGRectGetMinY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMinY(biggerRect))]; 

[maskPath moveToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMinY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMaxY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(smallerRect), CGRectGetMaxY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(smallerRect), CGRectGetMinY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMinY(smallerRect))]; 

mask.path = maskPath.CGPath; 
[mask setFillRule:kCAFillRuleEvenOdd]; 
mask.fillColor = [[UIColor blackColor] CGColor]; 
baseView.layer.mask = mask; 

回答

10

如果你問你是否能重塑面具,而不必每次繪製的路徑,可惜沒有。您可以保持蒙版形狀相同,並通過設置CAShapeLayertransform屬性對蒙版進行變形,但如果需要蒙版採取不同的形狀,則必須通過創建新路徑來繪製該形狀。 但是沒有必要從UIView中刪除蒙版,並在每次需要更改其形狀時創建一個全新的蒙版。只需設定CAShapeLayer的path財產,而它仍然掩蓋UIView足以使更改生效:

- (void)remask 
{ 
    CAShapeLayer *mask = (CAShapeLayer *)self.view.layer.mask; 

    CGRect biggerRect = CGRectMake(mask.frame.origin.x, mask.frame.origin.y, mask.frame.size.width, mask.frame.size.height); 
    CGRect smallerRect = CGRectMake(0.0f, 100.0f, 200.0f, 200.0f); 

    UIBezierPath *maskPath = [UIBezierPath bezierPath]; 
    [maskPath moveToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMinY(biggerRect))]; 
    [maskPath addLineToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMaxY(biggerRect))]; 
    [maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(biggerRect), CGRectGetMaxY(biggerRect))]; 
    [maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(biggerRect), CGRectGetMinY(biggerRect))]; 
    [maskPath addLineToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMinY(biggerRect))]; 

    [maskPath moveToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMinY(smallerRect))]; 
    [maskPath addLineToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMaxY(smallerRect))]; 
    [maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(smallerRect), CGRectGetMaxY(smallerRect))]; 
    [maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(smallerRect), CGRectGetMinY(smallerRect))]; 
    [maskPath addLineToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMinY(smallerRect))]; 

    mask.path = maskPath.CGPath; 
} 

在一個側面說明,你是知道的,而不是繪製每個矩形手動您可以創建使用以下代碼的掩碼路徑:

mask = [[CAShapeLayer alloc] init]; 
mask.frame = baseView.layer.bounds; 
CGRect biggerRect = CGRectMake(mask.frame.origin.x, mask.frame.origin.y, mask.frame.size.width, mask.frame.size.height); 
CGRect smallerRect = CGRectMake(0.0f, 100.0f, 200.0f, 200.0f); 

CGMutablePathRef maskPath = CGPathCreateMutable(); 
CGPathAddRect(maskPath, NULL, biggerRect); 
CGPathAddRect(maskPath, NULL, smallerRect); 

mask.path = maskPath; 
[mask setFillRule:kCAFillRuleEvenOdd]; 
mask.fillColor = [[UIColor blackColor] CGColor]; 
baseView.layer.mask = mask; 

CGPathRelease(maskPath); 

我想我只是指出它,因爲它可能對您來說是方便的。

+0

看起來不錯,但有什麼區別? – Alessandro 2013-03-29 13:38:28

+3

@Alessandro那麼結果是相同的,但除此之外:更少的代碼行+可讀性更強/更明顯+使用輕量級C API而不是「重量級」UIBezierPath對象,因此它可能性能稍微高一點。只是指出'AddRect'函數爲了將來的方便。實際上,我只是需要一些東西來陪伴我的答案的壞消息,希望你想做的事情不是直接可能的哈哈。 – 2013-03-30 13:04:40