在 drawRect 中绘制透明的 UIBezierPath 线
Draw transparent UIBezierPath line inside drawRect
我正在尝试在 drawRect 方法中实现透明路径。这是我创建的简单代码:
override func drawRect(rect: CGRect) {
let clippingPath = UIBezierPath()
UIColor.whiteColor().set();
clippingPath.moveToPoint(CGPoint(x: 10, y: CGRectGetHeight(self.bounds) / 2))
clippingPath.addLineToPoint(CGPoint(x: CGRectGetWidth(self.bounds) - 10, y: CGRectGetHeight(self.bounds) / 2))
clippingPath.lineWidth = 6
clippingPath.lineCapStyle = .Round
clippingPath.stroke()
}
这是结果:
有没有办法保持背景纯色但路径线透明。如果我将第二行更改为 UIColor.clearColor().set()
似乎没有任何反应,我只会得到一个完整的纯色背景(在本例中为黑色。
您想使用 kCGBlendModeDestinationOut
混合模式(和纯色描边)绘制路径。
According to the docs,此混合模式执行以下操作:
R = D*(1 - Sa)
在哪里...
R为预乘结果
S 是源颜色,包括 alpha
D 是目标颜色,包括 alpha
Ra、Sa 和 Da 是 R、S 和 D 的 alpha 分量
这样,当与纯色描边一起使用时,绘制的路径将为'transparent'。
clearColor
对你不起作用的原因是因为默认的混合模式是 additive,因此生成的颜色将不受绘制颜色的影响0
的 alpha 覆盖它。另一方面,DestinationOut
是 减法。
因此您需要执行以下操作:
override func drawRect(rect: CGRect) {
let clippingPath = UIBezierPath()
let context = UIGraphicsGetCurrentContext() // get your current context
// draw your background color
UIColor.greenColor().set();
CGContextFillRect(context, bounds)
CGContextSaveGState(context) // save the current state
CGContextSetBlendMode(context, .DestinationOut) // change blend mode to DestinationOut (R = D * (1-Sa))
// do 'transparent' drawing
UIColor.whiteColor().set();
clippingPath.moveToPoint(CGPoint(x: 10, y: CGRectGetHeight(self.bounds) / 2))
clippingPath.addLineToPoint(CGPoint(x: CGRectGetWidth(self.bounds) - 10, y: CGRectGetHeight(self.bounds) / 2))
clippingPath.lineWidth = 6
clippingPath.lineCapStyle = .Round
clippingPath.stroke()
CGContextRestoreGState(context) // restore state of context
// do further drawing if needed
}
注:
您必须将视图的 opaque
属性 设置为 false
才能正常工作,否则 UIKit 会假定它具有不透明的内容。例如:
override init(frame: CGRect) {
super.init(frame: frame)
opaque = false
}
另一种可能更简单的方法是将笔划的 CAShapeLayer
添加为要显示的视图的 maskLayer
,然后将颜色叠加层放在另一个视图后面视图被屏蔽。因此,只要标记的视图被遮盖,您的纯色就会出现。
我正在尝试在 drawRect 方法中实现透明路径。这是我创建的简单代码:
override func drawRect(rect: CGRect) {
let clippingPath = UIBezierPath()
UIColor.whiteColor().set();
clippingPath.moveToPoint(CGPoint(x: 10, y: CGRectGetHeight(self.bounds) / 2))
clippingPath.addLineToPoint(CGPoint(x: CGRectGetWidth(self.bounds) - 10, y: CGRectGetHeight(self.bounds) / 2))
clippingPath.lineWidth = 6
clippingPath.lineCapStyle = .Round
clippingPath.stroke()
}
这是结果:
有没有办法保持背景纯色但路径线透明。如果我将第二行更改为 UIColor.clearColor().set()
似乎没有任何反应,我只会得到一个完整的纯色背景(在本例中为黑色。
您想使用 kCGBlendModeDestinationOut
混合模式(和纯色描边)绘制路径。
According to the docs,此混合模式执行以下操作:
R = D*(1 - Sa)
在哪里...
R为预乘结果
S 是源颜色,包括 alpha
D 是目标颜色,包括 alpha
Ra、Sa 和 Da 是 R、S 和 D 的 alpha 分量
这样,当与纯色描边一起使用时,绘制的路径将为'transparent'。
clearColor
对你不起作用的原因是因为默认的混合模式是 additive,因此生成的颜色将不受绘制颜色的影响0
的 alpha 覆盖它。另一方面,DestinationOut
是 减法。
因此您需要执行以下操作:
override func drawRect(rect: CGRect) {
let clippingPath = UIBezierPath()
let context = UIGraphicsGetCurrentContext() // get your current context
// draw your background color
UIColor.greenColor().set();
CGContextFillRect(context, bounds)
CGContextSaveGState(context) // save the current state
CGContextSetBlendMode(context, .DestinationOut) // change blend mode to DestinationOut (R = D * (1-Sa))
// do 'transparent' drawing
UIColor.whiteColor().set();
clippingPath.moveToPoint(CGPoint(x: 10, y: CGRectGetHeight(self.bounds) / 2))
clippingPath.addLineToPoint(CGPoint(x: CGRectGetWidth(self.bounds) - 10, y: CGRectGetHeight(self.bounds) / 2))
clippingPath.lineWidth = 6
clippingPath.lineCapStyle = .Round
clippingPath.stroke()
CGContextRestoreGState(context) // restore state of context
// do further drawing if needed
}
注:
您必须将视图的 opaque
属性 设置为 false
才能正常工作,否则 UIKit 会假定它具有不透明的内容。例如:
override init(frame: CGRect) {
super.init(frame: frame)
opaque = false
}
另一种可能更简单的方法是将笔划的 CAShapeLayer
添加为要显示的视图的 maskLayer
,然后将颜色叠加层放在另一个视图后面视图被屏蔽。因此,只要标记的视图被遮盖,您的纯色就会出现。