UIView 中的 CAShapeLayer 抠图
CAShapeLayer cutout in UIView
我的目标是创建一个非常不透明的背景,带有清晰的圆角矩形插图
let shape = CGRect(x: 0, y: 0, width: 200, height: 200)
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: shape, cornerRadius: 16).cgPath
maskLayer.fillColor = UIColor.clear.cgColor
maskLayer.fillRule = kCAFillRuleEvenOdd
let background = UIView()
background.backgroundColor = UIColor.black.withAlphaComponent(0.8)
view.addSubview(background)
constrain(background) {
[=10=].edges == [=10=].superview!.edges
}
background.layer.addSublayer(maskLayer)
// background.layer.mask = maskLayer
当我取消注释 background.layer.mask = maskLayer
时,视图完全清晰。当我把它注释掉时,我看到了半透明的背景颜色,但没有遮罩切口
知道我做错了什么吗?谢谢!
您的遮罩层没有大小。
添加此行 maskLayer.frame = shape
而且你不需要background.layer.addSublayer(maskLayer)
这是一个我认为可以实现您预期效果的游乐场(减去 .edges
和 constrain
- 这似乎是您自己的扩展)。
a) 使用红色背景而不是带 alpha 的黑色(只是为了突出效果)
b) 设置 maskLayer.backgroundColor
而不是 maskLayer.fillColor
将 maskLayer 作为另一层添加到 uiview
是多余的(如 @Ken 所指出的),但似乎没有害处。
import UIKit
import PlaygroundSupport
let bounds = CGRect(x: 0, y: 0, width: 400, height: 200)
let uiview = UIView(frame: bounds)
uiview.backgroundColor = UIColor.red.withAlphaComponent(0.8)
PlaygroundPage.current.liveView = uiview
let shape = CGRect(x: 100, y: 50, width: 200, height: 100)
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: shape, cornerRadius: 16).cgPath
maskLayer.backgroundColor = UIColor.clear.cgColor
maskLayer.fillRule = kCAFillRuleEvenOdd
uiview.layer.mask = maskLayer
image of clear inset
另一方面,如果您想要像下面这样的相框/带透明的彩色信封window效果,请参阅gist
image of picture frame
我的目标是创建一个非常不透明的背景,带有清晰的圆角矩形插图
let shape = CGRect(x: 0, y: 0, width: 200, height: 200)
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: shape, cornerRadius: 16).cgPath
maskLayer.fillColor = UIColor.clear.cgColor
maskLayer.fillRule = kCAFillRuleEvenOdd
let background = UIView()
background.backgroundColor = UIColor.black.withAlphaComponent(0.8)
view.addSubview(background)
constrain(background) {
[=10=].edges == [=10=].superview!.edges
}
background.layer.addSublayer(maskLayer)
// background.layer.mask = maskLayer
当我取消注释 background.layer.mask = maskLayer
时,视图完全清晰。当我把它注释掉时,我看到了半透明的背景颜色,但没有遮罩切口
知道我做错了什么吗?谢谢!
您的遮罩层没有大小。
添加此行 maskLayer.frame = shape
而且你不需要background.layer.addSublayer(maskLayer)
这是一个我认为可以实现您预期效果的游乐场(减去 .edges
和 constrain
- 这似乎是您自己的扩展)。
a) 使用红色背景而不是带 alpha 的黑色(只是为了突出效果)
b) 设置 maskLayer.backgroundColor
而不是 maskLayer.fillColor
将 maskLayer 作为另一层添加到 uiview
是多余的(如 @Ken 所指出的),但似乎没有害处。
import UIKit
import PlaygroundSupport
let bounds = CGRect(x: 0, y: 0, width: 400, height: 200)
let uiview = UIView(frame: bounds)
uiview.backgroundColor = UIColor.red.withAlphaComponent(0.8)
PlaygroundPage.current.liveView = uiview
let shape = CGRect(x: 100, y: 50, width: 200, height: 100)
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: shape, cornerRadius: 16).cgPath
maskLayer.backgroundColor = UIColor.clear.cgColor
maskLayer.fillRule = kCAFillRuleEvenOdd
uiview.layer.mask = maskLayer
image of clear inset
另一方面,如果您想要像下面这样的相框/带透明的彩色信封window效果,请参阅gist
image of picture frame