8

このコードを使用して、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;

切り取りたい長方形が変わるので、UIviewからマスクを削除して別の寸法で再適用するのではなく、マスクのサイズをすばやく変更する方法があるかどうか疑問に思いました。

例えば

[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;
4

1 に答える 1

11

毎回パスを描画せずにマスクの形状を変更できるかどうかを尋ねる場合は、残念ながらできません。マスクの形状を同じに保ち、の変換プロパティを設定することでマスクの変換を実行CAShapeLayerできますが、マスクを別の形状にする必要がある場合は、新しいパスを作成してその形状を描画する必要があります。ただし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);

将来的には便利かもしれないので、指摘したいと思います。

于 2013-03-28T20:40:02.130 に答える