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

Swift自定义UIView初始化时自定义属性传值为nil如何解决

问题原因

打印得到nil是Swift初始化调用顺序导致的,核心逻辑如下:

  • convenience init(colorOfGradient:)属于便利构造器,按照Swift构造规则,便利构造器必须先调用当前类的指定构造器,也就是你代码里的init(frame:)
  • 执行self.init(frame: CGRect.zero)时会立刻进入override init(frame:)的方法实现,此时还没执行self.colorOfGradient = colorOfGradient的赋值逻辑,colorOfGradient还是默认的nil,打印自然拿不到值
  • 等init(frame:)执行完毕回到便利构造器,才会给colorOfGradient属性赋值,但这时候init(frame:)里的打印代码早就运行结束了。

另外你当前代码还漏了UIView子类必须实现的required init?(coder:)构造器,会触发编译报错。

修复方案

你可以根据自己的代码习惯选下面任意一种方案:

方案1:拆分UI配置逻辑,把依赖自定义属性的逻辑挪到赋值后执行

保留现有便利构造器的写法,把不依赖自定义属性的基础UI配置放在init(frame:)里,依赖colorOfGradient的逻辑等属性赋值完成后再调用,参考实现:

class WarningView: UIView {
    var colorOfGradient: String?
    
    convenience init(colorOfGradient: String?) {
        self.init(frame: .zero)
        self.colorOfGradient = colorOfGradient
        // 所有依赖colorOfGradient的逻辑,放在赋值后执行
        setupGradientStyle()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        // 这里只做不依赖自定义参数的基础配置
        setupBaseConfig()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupBaseConfig() {
        // 比如设置统一的圆角、遮罩、子视图约束这类通用逻辑
    }
    
    private func setupGradientStyle() {
        print(colorOfGradient as Any) // 此处可正确拿到传入的"red"
        // 编写渐变层的绘制、颜色配置逻辑
    }
}

方案2:自定义指定构造器,初始化时优先给自定义属性赋值

如果需要在构造方法内部就拿到colorOfGradient的值做配置,可以直接自定义指定构造器,给frame参数加默认值,既不影响原有调用方式,还能保证属性在调用父类构造器前就完成赋值:

class WarningView: UIView {
    var colorOfGradient: String?
    
    // 给frame参数加默认值.zero,调用时可以不传frame
    init(frame: CGRect = .zero, colorOfGradient: String?) {
        // 先给当前类的自定义属性赋值
        self.colorOfGradient = colorOfGradient
        // 再调用父类的指定构造器
        super.init(frame: frame)
        print(self.colorOfGradient as Any) // 此处可正确打印传入的"red"
        // 可以直接在这里编写所有依赖colorOfGradient的配置逻辑
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

这个方案下你原来的调用代码WarningView(colorOfGradient: color)不需要做任何修改,编译器会自动匹配到这个带默认参数的构造器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:54:32