自定义 UIView 中的无效上下文 0x0 - 后续问题

invalid context 0x0 within custom UIView - follow-up question

这个post: ...应该给我解决问题的关键,但我无法避免无效上下文错误。一些澄清将不胜感激。

我想在 ViewController 加载时显示的子视图中画线。为此,我为 UIView 创建了一个子类,它类似于由 StartPlayer 编辑的 SplitCircleView post。

到运行代码,创建一个新项目并将ViewController文件的内容替换为:

import UIKit
@IBDesignable

class ViewController: UIViewController {
    let mySubViewInstance = SplitCircleView()

    override func viewDidLoad() {
        super.viewDidLoad()

        //let mySubViewInstance = SplitCircleView()
        mySubViewInstance.setNeedsDisplay(mySubViewInstance.frame)
    }
}

class SplitCircleView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        //self.setNeedsDisplay()
        //draw(frame)
    }

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

    override func setNeedsDisplay(_ rect: CGRect) {
        self.backgroundColor = .clear

        drawSlice(rect: rect, startPercent: 87.5, endPercent: 37.5, color: .green)
        drawSlice(rect: rect, 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()
    }
}

如何避免无效上下文错误并在 ViewController 加载时在子视图中绘制内容?

您应该覆盖 draw,而不是 setNeedsDisplay

override func draw(_ rect: CGRect) {
    self.backgroundColor = .clear

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

而且背景颜色的设置只需要设置一次,所以 draw 并不是该行的理想位置。将其移动到 init.

setNeedsDisplay表示绘图需要更新。但实际绘制的是draw

有两个地方需要修改。

您正在创建一个新视图,因此您需要添加到 viewController

的视图
 override func viewDidLoad() {
    super.viewDidLoad()

    let mySubViewInstance = SplitCircleView.init(frame: self.view.bounds)
    self.view.addSubview(mySubViewInstance)

  //  mySubViewInstance.setNeedsDisplay(mySubViewInstance.frame)
}

第二个是绘制函数不使用 setNeedsDisplay();

override func draw(_ rect: CGRect) {

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

这样,你的美图就在这里。