自定义 UIView 中的无效上下文 0x0

invalid context 0x0 within custom UIView

我有以下自定义视图代码。

@IBDesignable class SplitCircleView: UIView {

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

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

    override func draw(_ rect: CGRect) {

        self.backgroundColor = .clear

        drawSlice(rect: self.frame, startPercent: 87.5, endPercent: 37.5, color: .green)
        drawSlice(rect: self.frame, startPercent: 37.5, endPercent: 87.5, color: .red)
    }

    func drawSlice(rect: CGRect, startPercent: CGFloat, endPercent: CGFloat, color: UIColor) {

        let center = CGPoint(x: rect.origin.x + rect.width / 2, y: rect.origin.y + rect.height / 2)
        let radius = (min(rect.width, rect.height) / 2)
        let startAngle = startPercent / 100 * .pi * 2 - .pi
        let endAngle = endPercent / 100 * .pi * 2 - .pi
        let path = UIBezierPath()

        path.move(to: center)
        path.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
        path.close()
        color.setFill()

        path.fill()
    }
}

我正在尝试用两个不同颜色的半圆画一个圆。

当我在 playground 实时取景中查看它时,它看起来不错。一旦我把它放在一个应用程序中,它就会给我带来问题。当代码尝试执行 color.setFill() 和 path.fill() 时,我在日志中收到以下错误。

2018-06-01 14:37:08.118005+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextSetFillColorWithColor: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118055+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118094+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextSetFlatness: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118141+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextAddPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118184+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextDrawPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118222+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118336+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextSetFillColorWithColor: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118376+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118413+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextSetFlatness: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118451+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextAddPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118491+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextDrawPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. 2018-06-01 14:37:08.118528+0100 SplitCircleView[21353:2290599] [Unknown process name] CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

我做错了什么,我该如何解决?

draw(_ rect: CGRect) 函数的文档中。 (最后一段"Discussion"。)

You should never call this method directly yourself.

如果你想触发这个功能你应该使用...

self.setNeedsDisplay()

Documentation for the draw function.

不过

正如@vacawama 所指出的(我错过了),绘制函数将在将您的视图添加到视图层次结构之后调用。所以你根本不需要在这里调用它。它会自动为您发生。

所以在 init 方法中,完全删除调用。

再次调用它的地方是如果视图改变形状或者如果你想改变它的内容。即颜色,或其他东西。