Ios 在drawRect内绘制透明的UIBezierPath线

Ios 在drawRect内绘制透明的UIBezierPath线,ios,core-graphics,drawrect,uibezierpath,Ios,Core Graphics,Drawrect,Uibezierpath,我试图在drawRect方法中实现透明路径。这是我创建的简单代码: override func drawRect(rect: CGRect) { let clippingPath = UIBezierPath() UIColor.whiteColor().set(); clippingPath.moveToPoint(CGPoint(x: 10, y: CGRectGetHeight(self.bounds) / 2)) clippingPath.addLine

我试图在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
(和纯色笔划)绘制路径。

,此混合模式执行以下操作:

R=D*(1-Sa)

在哪里

  • R是预乘的结果

  • S是源颜色,包括alpha

  • D是目标颜色,包括alpha

  • Ra、Sa和Da是R、S和D的α分量

这样,当与纯色笔划颜色一起使用时,绘制的路径将是“透明的”。

clearColor
不适用于您的原因是,默认的混合模式是加法模式,因此绘制alpha为
0
的颜色时,合成颜色将不受影响。
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
}
注意:

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
,然后将颜色覆盖在另一个视图中,隐藏视图的后面。因此,无论标记视图隐藏在何处,您的纯色都会出现。

谢谢。我已经尝试过了,howe我现在得到了一条黑线。我在一个红色的uiview上添加了这个视图,希望看到一条红线,但它仍然显示为黑色。啊,是的,我忘了提到你应该将
uiview
backgroundColor
设置为
clearColor
。然后你可以从
drawRect中绘制背景色e> 。这样做应该可以解决问题。@Tomus85嗯,奇怪…对我来说很有用。。你确定你没有从子类本身中将
backgroundColor
更改为
clearColor
以外的任何内容吗?谢谢,你是个明星。我错过了
UIColor.greenColor().set();CGContextFillRect(上下文,边界)
@Tomus85实际上,确保UIKit保持视图透明的更好方法是将
不透明
属性设置为
,而不是与
背景色
混在一起。我已经更新了我的答案:)