代码之家  ›  专栏  ›  技术社区  ›  Tomus85

在drawRect内绘制透明UIBezierPath线

  •  2
  • Tomus85  · 技术社区  · 8 年前

    我试图在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()
    }
    

    这就是结果:

    enter image description here

    有没有一种方法可以保持背景是实心的,但路径线是透明的。如果我将第二行更改为 UIColor.clearColor().set() 似乎什么都没有发生,我只得到了一个完整的纯色背景(在本例中为黑色)。

    2 回复  |  直到 8 年前
        1
  •  3
  •   Hamish    8 年前

    您希望以混合模式绘制路径 kCGBlendModeDestinationOut (和纯色笔划)。

    According to the docs ,此混合模式执行以下操作:

    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
    }
    

    注:

    你必须设置 opaque 视图的属性 false 否则UIKit将假定其内容不透明。例如:

    override init(frame: CGRect) {
        super.init(frame: frame)
        opaque = false
    }
    
        2
  •  0
  •   Rob Md Fahim Faez Abir    8 年前

    另一种可能更简单的方法是添加笔划 CAShapeLayer 作为一个 maskLayer 然后将颜色覆盖放在被遮罩的视图后面的另一个视图中。因此,只要标记的视图被遮蔽,就会显示纯色。