Search code examples
iosswiftuiviewuibezierpathshapes

UIView background color always BLACK while drawing UIBezierPath


I'm adding ShapeView which is subclass of UIView to View Controller in which I'm drawing Bezier Path and the background of that view always stays black. I tried to fix my problem with answers from UIView Background Color Always Black and Cant Change UIView Background Color From Black but, unfortunately, no results.

The gradient green is shape, and the black areas under shape should be white.

enter image description here

Here is code from ShapeView class.

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()
    }
}

Any ideas what to do?


Solution

  • I think you can add those two lines to func draw(_ rect: CGRect) just after super.draw(rect):

    UIColor.white.setFill()
    UIRectFill(rect)
    

    so the method looks like this:

    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()
    }
    

    If you need other background-colour you can change white in: UIColor.white.setFill() to needed colour.