2012-06-01 29 views
7

我試圖裁剪一個圖層,但是,而不是創建一個蒙版(B)和裁剪圖層(A)獲得裁剪圖層A的形狀爲B,我想以獲得具有形狀A和通過使用層B裁剪而創建的'洞'的層。裁剪一個CAShapeLayer檢索外部路徑

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

如何獲得裁剪圖層A?

回答

20

你必須創建一個覆蓋你想要的區域的掩碼保持。這可以通過使用偶數填充規則來完成,併爲具有兩個矩形的形狀圖層創建路徑。您可以像這樣創建形狀(其中兩個矩形將是您的兩個框架)。然後,將其設置爲掩碼以獲得您之後的結果。

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

夫特3.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) 
    } 
}