自定义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
相关产品推荐
相关产品推荐

