Search code examples
iosswiftquartz-graphicsquartz-core

CALayer sublayer shows up but context drawing within it not working


I created a custom UIView class where I override the draw(_ rect: CGRect) function. In it, I added a gradient (CAGradientLayer) sublayer (which works without much problem) and then add another sublayer above it, a custom 'CloseLayer' class that inherits from CALayer.

That second sublayer I add gets correctly added in front with the right dimensions, however the line drawing I implemented in the draw(in ctx: CGContext) function of the custom CALayer class doesn't seem to be doing anything. I have been looking at several resources and googling for the past few days and am started to get a bit discouraged. Below is my code for the UIView class (that contains the two sublayers) and the custom layer class I want drawing to occur in. Any help is much appreciated!

class GraphAView: UIView {
    // trading 9:00AM EST to 6:00PM EST
    // Normal: 9:30AM EST to 4:00PM EST
    // 9 hours total, 5 min intervals (12 intervals per hour, 108 total)
    let HonchoGreyComponents : [CGFloat] = [0.2,0.2,0.2,1.0]
    let graphBackGreyComponents: [CGFloat] = [0.8,0.8,0.8,1.0]


    override func draw(_ rect: CGRect) {
        setUpBack()
    }

    func setUpBack(){
        let RGBSpace = CGColorSpaceCreateDeviceRGB()
        let HonchoGrey = CGColor(colorSpace: RGBSpace, components: HonchoGreyComponents)
        let graphBackGrey = CGColor(colorSpace: RGBSpace, components: graphBackGreyComponents)
        let Gradlayer = CAGradientLayer()
        Gradlayer.frame = self.bounds
        Gradlayer.colors = [HonchoGrey!,graphBackGrey!,graphBackGrey!,HonchoGrey!]
        //layer.locations = [NSNumber(value: PreMarketEnd),NSNumber(value: RegMarketEnd)]
        Gradlayer.locations = [0,0.055555, 0.7777777]
        Gradlayer.startPoint = CGPoint(x: 0, y: 0)
        Gradlayer.endPoint =  CGPoint(x: 1, y: 0)
        self.layer.insertSublayer(Gradlayer, at: 0)
        let closingLay = CloseLayer()
        closingLay.frame = self.bounds
        let yer = UIColor(red: 0.3, green: 0.6, blue: 0.8, alpha: 1.0)
        //closingLay.backgroundColor = UIColor.blue.cgColor
        //closingLay.backgroundColor = UIColor(white: 0.4, alpha: 0.0).cgColor
        closingLay.backgroundColor = yer.cgColor
        self.layer.insertSublayer(closingLay, above: Gradlayer)
        closingLay.setNeedsDisplay()
        self.layer.setNeedsDisplay()
    }
}
class CloseLayer: CALayer {

    let ClosinglineWidth: CGFloat = 4.0
    let dashPattern: [CGFloat] = [2,2]

    override func draw(in ctx: CGContext) {

        let CloseContext = UIGraphicsGetCurrentContext()
        let middleY = self.frame.height / 2
       // let width = self.frame.width
       // let context = UIGraphicsGetCurrentContext()
        CloseContext?.setLineWidth(ClosinglineWidth)
        CloseContext?.setLineDash(phase: 1, lengths: dashPattern)
        CloseContext?.move(to: CGPoint(x: 0, y: middleY))
        CloseContext?.addLine(to: CGPoint(x: self.frame.width, y: middleY)) // 358 width
        let closingLineColor = UIColor.red.cgColor
        CloseContext?.setStrokeColor(closingLineColor)
        CloseContext?.strokePath()
    }

    func drawLine(start: CGPoint, end: CGPoint){

    }
}

Solution

  • The problem is this line:

    let CloseContext = UIGraphicsGetCurrentContext()
    

    There is no current context. Your job is to draw into ctx, the context you were handed.

    Long story short, change that line to:

    let CloseContext : CGContext? = ctx
    

    ...and bingo, you will see your line. (But that is just for instant gratification. In the end, you should get rid of CloseContext everywhere and subsitute ctx.)