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

自定义UIView中draw(_ rect: CGRect)方法未被调用的问题

我来帮你梳理下这个问题的排查方向,毕竟Storyboard里自定义视图的draw(_:)方法不触发是个挺常见的坑😉

常见排查步骤

以下是按优先级排序的排查点,你可以逐一验证:

  • 检查是否调用了setNeedsDisplay()
    系统不会自动在init?(coder:)完成后触发绘制,如果你在初始化时没有通知视图需要重绘,draw(_:)就不会被调用。在init?(coder:)方法末尾加上self.setNeedsDisplay(),强制系统触发绘制流程。这很可能是你“另一种写法能工作”的核心原因——另一种写法里大概率加了这个调用。

  • 验证draw(_:)方法签名是否完全正确
    确保方法签名没有拼写错误,且带有override关键字,正确格式应该是:

    override func draw(_ rect: CGRect) {
        // 你的绘制逻辑
    }
    

    要是漏掉override、参数名写错(比如把rect写成frame),系统会把它当成普通方法,不会自动调用。

  • 检查isOpaque属性设置
    如果你的视图设置了isOpaque = true,但draw(_:)里没有完全填充整个rect区域,系统可能会跳过绘制。可以尝试把isOpaque设为false,或者确保绘制代码覆盖了整个视图范围。

  • 确认Storyboard视图的类关联是否正确
    虽然init?(coder:)能触发,但还是要再核对一遍:选中Storyboard里的目标视图,在Identity Inspector的Class字段是否准确填写了你的自定义视图类名,Module选项有没有选对(尤其是多Target或使用CocoaPods的场景)。

  • 检查layoutSubviews()的重写逻辑
    如果你重写了layoutSubviews()但忘记调用super.layoutSubviews(),会打乱视图的布局与绘制流程。确保自定义的layoutSubviews()里第一行就是super.layoutSubviews()。

  • 代码中手动实例化测试
    在ViewController的viewDidLoad里手动创建一个你的自定义视图实例并添加到界面上:

    let circleView = CircleView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
    view.addSubview(circleView)
    

    如果这样draw(_:)能触发,说明问题出在Storyboard的配置上;如果还是不触发,那就是自定义视图本身的逻辑问题。

参考正确实现示例

这里给你一个能正常工作的自定义圆形视图代码,你可以对照调整:

import UIKit

class CircleView: UIView {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonSetup()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonSetup()
    }
    
    private func commonSetup() {
        backgroundColor = .clear
        isOpaque = false
        setNeedsDisplay() // 强制触发绘制
    }
    
    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }
        
        // 绘制中心圆形
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let radius = min(rect.width, rect.height) / 2 - 5
        
        context.setStrokeColor(UIColor.systemBlue.cgColor)
        context.setLineWidth(3)
        context.addArc(center: center, radius: radius, startAngle: 0, endAngle: .pi * 2, clockwise: true)
        context.strokePath()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:25:07