【问题标题】:Draw transparent UIBezierPath line inside drawRect在drawRect内绘制透明的UIBezierPath线
【发布时间】:2016-03-01 13:58:43
【问题描述】:

我正在尝试在 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() 似乎什么也没发生,我只会得到一个完整的纯色背景色(在这种情况下为黑色。

【问题讨论】:

    标签: ios core-graphics drawrect uibezierpath


    【解决方案1】:

    您想以kCGBlendModeDestinationOut 的混合模式(和纯色笔触)绘制路径。

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

    R = D*(1 - Sa)

    在哪里...

    • R 是预乘结果。

    • S 是源颜色,包括 alpha

    • D 是目标颜色,包括 alpha

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

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

    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
    }
    

    【讨论】:

    • 谢谢。我已经尝试过了,但是我现在得到了一条黑线。我在红色 uiview 上添加了这个视图,希望看到一条红线,但它仍然显示为黑色
    • 啊,是的,我忘了提到你应该将UIViewbackgroundColor 设置为clearColor。然后,您可以从drawRect 中绘制背景颜色。这样做应该可以解决问题。
    • @Tomus85 嗯,很奇怪……对我有用。 Have a look at this project I just put together。您确定您没有从子类本身将backgroundColor 更改为clearColor 以外的任何内容吗?
    • 谢谢你,你是明星。我错过了UIColor.greenColor().set(); CGContextFillRect(context, bounds)
    • @Tomus85 实际上确保 UIKit 保持视图透明的更好方法是将opaque 属性设置为false,而不是弄乱backgroundColor。我已经用这个更新了我的答案:)
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      • 2010-09-13
      相关资源
      最近更新 更多