Pytanie w sprawie uikit, core-graphics, objective-c, calayer – Przytnij warstwę CAShapeLayer, pobierając zewnętrzną ścieżkę

7

Próbuję przyciąć warstwę innym, ale zamiast tworzyć maskę (B) i przyciąć warstwę (A), uzyskując przyciętą warstwę A o kształcie B, chcę uzyskać warstwę o kształcie A i a ' otwór ”utworzony przez przycięcie warstwą B.

*************               ***Layer A***
*  Layer A  *               *************
*   *****   *               ****    *****
*   * B *   *      ->       ****    ***** Layer A without shape B
*   *****   *               ****    *****
*           *               *************
*************               *************

Jak mogę uzyskać przyciętą warstwę A?

Twoja odpowiedź

2   odpowiedź
0

class MakeTransparentHoleOnOverlayView: UIView {

    @IBOutlet weak var transparentHoleView: UIView!

    // MARK: - Drawing

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        if self.transparentHoleView != nil {
            // Ensures to use the current background color to set the filling color
            self.backgroundColor?.setFill()
            UIRectFill(rect)

            let layer = CAShapeLayer()
            let path = CGMutablePath()

            // Make hole in view's overlay
            // NOTE: Here, instead of using the transparentHoleView UIView we could use a specific CFRect location instead...
            path.addRect(transparentHoleView.frame)
            path.addRect(bounds)

            layer.path = path
            layer.fillRule = kCAFillRuleEvenOdd
            self.layer.mask = layer
        }
    }

    override func layoutSubviews () {
        super.layoutSubviews()
    }

    // MARK: - Initialization

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }
}
20

która obejmuje obszar, który chcesztrzymać. Można to zrobić za pomocą reguły wypełnienia parzystego i nieparzystego i utworzyć ścieżkę dla warstwy kształtu z obydwoma prostokątami. Możesz utworzyć taki kształt (gdzie dwa prostokąty będą twoimi dwiema ramkami). Następnie ustawiasz to jako maskę, aby uzyskać wynik, po którym jesteś.

CAShapeLayer *maskWithHole = [CAShapeLayer layer];

// Both frames are defined in the same coordinate system
CGRect biggerRect = CGRectMake(30, 50, 120, 200);
CGRect smallerRect = CGRectMake(80, 100, 50, 80);

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))];

[maskWithHole setPath:[maskPath CGPath]];
[maskWithHole setFillRule:kCAFillRuleEvenOdd];
[maskWithHole setFillColor:[[UIColor orangeColor] CGColor]];

Powiązane pytania