【问题标题】:UIView background color always BLACK while drawing UIBezierPath绘制 UIBezierPath 时 UIView 背景颜色始终为黑色
【发布时间】:2019-10-28 17:39:08
【问题描述】:

我正在将 UIView 的子类 ShapeView 添加到视图控制器中,在该控制器中我正在绘制 Bezier 路径,并且该视图的背景始终保持黑色。我试图通过UIView Background Color Always Black 和Cant Change UIView Background Color From Black 的回答来解决我的问题,但不幸的是,没有结果。

渐变绿色为shape,shape下的黑色区域为白色。

这是来自 ShapeView 类的代码。

class ShapeView: UIView {

    //// Color Declarations
    // Green - Storage
    let gradientColor0 = UIColor(red: 0.082, green: 0.608, blue: 0.486, alpha: 1.000)
    let gradientColor1 = UIColor(red: 0.502, green: 0.980, blue: 0.949, alpha: 1.000)

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.isOpaque = false
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        //// General Declarations
        let context = UIGraphicsGetCurrentContext()!

        //// Gradient Declarations
        let paint0_linear2 = CGGradient(colorsSpace: nil, colors: [gradientColor0.cgColor, gradientColor1.cgColor] as CFArray, locations: [0, 1])!

        //// Bezier Drawing
        let bezierPath = UIBezierPath()
        bezierPath.move(to: CGPoint(x: 0, y: 342))
        bezierPath.addLine(to: CGPoint(x: 187.5, y: 372))
        bezierPath.addLine(to: CGPoint(x: 375, y: 342))
        bezierPath.addLine(to: CGPoint(x: 375, y: 0))
        bezierPath.addLine(to: CGPoint(x: 0, y: 0))
        bezierPath.addLine(to: CGPoint(x: 0, y: 342))
        bezierPath.close()
        bezierPath.usesEvenOddFillRule = true
        context.saveGState()
        bezierPath.addClip()
        context.drawLinearGradient(paint0_linear2,
                                   start: CGPoint(x: 363.75, y: -664.71),
                                   end: CGPoint(x: 900.13, y: 234.82),
                                   options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])
        context.restoreGState()
    }
}

有什么想法吗?

【问题讨论】:

  • 尝试将colorsSpace 设置为CGColorSpaceCreateDeviceRGB。
  • 设置 view.isOpaque = false 就知道了!

标签: ios swift uiview uibezierpath shapes


【解决方案1】:

您可能会发现这更容易使用...

@IBDesignable
class JurkoShapeView: UIView {

    override open class var layerClass: AnyClass {
        return CAGradientLayer.classForCoder()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    func commonInit() -> Void {

        if let l = layer as? CAGradientLayer {

            let gradientColor0 = UIColor(red: 0.082, green: 0.608, blue: 0.486, alpha: 1.000)
            let gradientColor1 = UIColor(red: 0.502, green: 0.980, blue: 0.949, alpha: 1.000)

            l.colors = [gradientColor0.cgColor, gradientColor1.cgColor]
            l.startPoint = CGPoint(x: 0.0, y: 0.0)
            l.endPoint = CGPoint(x: 0.0, y: 1.0)
        }

    }

    override func layoutSubviews() {
        super.layoutSubviews()

        let l = CAShapeLayer()

        let y1 = bounds.size.height - 30

        let bezierPath = UIBezierPath()
        bezierPath.move(to: CGPoint(x: 0, y: 0))
        bezierPath.addLine(to: CGPoint(x: bounds.maxX, y: 0))
        bezierPath.addLine(to: CGPoint(x: bounds.maxX, y: y1))
        bezierPath.addLine(to: CGPoint(x: bounds.midX, y: bounds.maxY))
        bezierPath.addLine(to: CGPoint(x: 0, y: y1))
        bezierPath.close()

        l.path = bezierPath.cgPath

        self.layer.mask = l

    }
}

通过将其设为@IBDesignable,您可以在 Storyboard 中进行设计时看到它:

【讨论】:

  • 我正准备在我的回复中添加一条评论,最好使用CAGradientLayer 并用CAShapeLayer 掩盖它,但@DonMag 已经这样做了。
  • lazy var gradientLayer是什么意思?我的意思是你从未使用过它。
  • @LeoDabus - 哎呀......来自旧方法(留在里面)......编辑了我的答案并将其删除。
  • 感谢您的回答@DonMag。我将我的代码重写为您的版本,它更易于使用,并且您节省了我将贝塞尔绘图从静态点修复为动态点的时间,具体取决于视图大小。
【解决方案2】:

我认为你可以在func draw(_ rect: CGRect) 之后将这两行添加到super.draw(rect):

UIColor.white.setFill()
UIRectFill(rect)

所以方法看起来像这样:

override func draw(_ rect: CGRect) {
    super.draw(rect)

    UIColor.white.setFill()
    UIRectFill(rect)

    //// General Declarations
    let context = UIGraphicsGetCurrentContext()!



    //// Gradient Declarations
    let paint0_linear2 = CGGradient(colorsSpace: nil, colors: [gradientColor0.cgColor, gradientColor1.cgColor] as CFArray, locations: [0, 1])!

    //// Bezier Drawing
    let bezierPath = UIBezierPath()
    bezierPath.move(to: CGPoint(x: 0, y: 342))
    bezierPath.addLine(to: CGPoint(x: 187.5, y: 372))
    bezierPath.addLine(to: CGPoint(x: 375, y: 342))
    bezierPath.addLine(to: CGPoint(x: 375, y: 0))
    bezierPath.addLine(to: CGPoint(x: 0, y: 0))
    bezierPath.addLine(to: CGPoint(x: 0, y: 342))
    bezierPath.close()
    bezierPath.usesEvenOddFillRule = true
    context.saveGState()
    bezierPath.addClip()
    context.drawLinearGradient(paint0_linear2,
                               start: CGPoint(x: 363.75, y: -664.71),
                               end: CGPoint(x: 900.13, y: 234.82),
                               options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])
    context.restoreGState()
}

如果您需要其他背景颜色,您可以将white 中的UIColor.white.setFill() 更改为所需颜色。

【讨论】:

  • 或者你可以设置 view.isOpaque = false
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
  • 2017-05-30
  • 2013-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
相关资源
最近更新 更多