【问题标题】:Crop a CAShapeLayer retrieving the external path裁剪 CAShapeLayer 以检索外部路径
【发布时间】:2012-06-07 01:16:48
【问题描述】:
我正在尝试用其他图层裁剪图层,但是,我不是创建蒙版 (B) 并裁剪图层 (A),而是得到一个形状为 B 的裁剪图层 A,我想得到一个形状为 A 的图层以及通过 B 层裁剪创建的“洞”。
************* ***Layer A***
* Layer A * *************
* ***** * **** *****
* * B * * -> **** ***** Layer A without shape B
* ***** * **** *****
* * *************
************* *************
如何获得裁剪后的图层 A?
【问题讨论】:
标签:
objective-c
uikit
core-graphics
calayer
【解决方案1】:
您必须创建一个覆盖您想要保留的区域的遮罩。这可以通过使用奇偶填充规则并为具有两个矩形的形状图层创建路径来完成。您可以像这样创建形状(两个矩形将是您的两个框架)。然后你将它设置为掩码以获得你想要的结果。
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]];
【解决方案2】:
Swift 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)
}
}