You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义UIView出现invalid context 0x0错误的原因与修复

问题分析与修复方案

你遇到的invalid context 0x0错误,核心原因是在视图初始化阶段手动调用了draw(frame)方法——这时候UIKit还没有为视图创建有效的绘图上下文(CGContext),直接调用绘图相关的方法自然会报错。Playground预览能正常显示是因为它的运行环境和正式App的视图生命周期逻辑略有不同。

具体修复步骤:

  • 移除init方法里的手动绘图调用:UIKit会在视图需要渲染时自动调用draw(_ rect:)方法,不需要你在init(frame:)和init?(coder:)里手动触发。
  • 使用传入的rect参数而非self.frame:draw(_ rect:)方法的rect参数是当前视图的实际绘图区域,用它来计算圆心和半径比self.frame更准确(比如视图被布局调整后,frame和rect可能不一致)。

修改后的完整代码:

@IBDesignable class SplitCircleView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupView()
    }
    
    private func setupView() {
        backgroundColor = .clear
    }
    
    override func draw(_ rect: CGRect) {
        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.midX, y: rect.midY)
        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()
    }
}

额外说明:

我把设置backgroundColor的逻辑放到了setupView方法里,这样代码更整洁,也避免在draw(_:)里重复设置(虽然这里影响不大,但这是更规范的实践);同时用rect.midX和rect.midY替代手动计算圆心,让代码更简洁易读。

这样修改后,App里的视图就能正常渲染,不会再出现上下文错误了。

内容的提问来源于stack exchange,提问作者StartPlayer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:06:42