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

Swift中如何正确创建初始化器?自定义UIView初始化实现问题

正确实现NewFormView的自定义初始化器

你之前的问题出在调用了错误的父类初始化方法——UIView根本没有init(user:)这个初始化器,咱们得按照Swift的初始化规则来实现。

核心思路

UIView有两个指定初始化器:

  • init(frame: CGRect):用于纯代码创建视图
  • init?(coder: NSCoder):用于从xib/storyboard加载视图

我们需要给NewFormView添加一个便利初始化器,接收Users对象,先初始化自己的viewModel,再调用父类的指定初始化器。

完整代码实现

class NewFormViewModel {
    let user: Users
    
    init(for user: Users) {
        self.user = user
    }
}

class NewFormView: UIView {
    // 存储属性必须在初始化时赋值
    var viewModel: NewFormViewModel
    
    // 自定义便利初始化器:接收Users对象
    init(user: Users) {
        // 第一步:先初始化自己的存储属性
        self.viewModel = NewFormViewModel(for: user)
        // 第二步:调用UIView的指定初始化器(这里传.zero表示默认无尺寸,后续可以通过AutoLayout调整)
        super.init(frame: .zero)
        // 第三步:可选的视图配置逻辑(比如设置背景色、添加子视图等)
        setupView()
    }
    
    // 必须实现的coder初始化器(如果不支持从xib加载,直接抛出错误即可)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented. Use init(user:) instead.")
    }
    
    // 视图配置辅助方法
    private func setupView() {
        backgroundColor = .systemBackground
        // 这里可以添加子视图、设置约束等
    }
}

为什么这么写?

  1. 初始化顺序:Swift要求在调用父类初始化器之前,必须先初始化当前类的所有存储属性(也就是viewModel),所以我们先创建NewFormViewModel实例。
  2. 父类初始化器:必须调用UIView的指定初始化器,这里用init(frame: .zero)是最常用的纯代码初始化方式,后续可以通过AutoLayout来设置视图的大小和位置。
  3. coder初始化器:如果你的项目中不需要从xib或storyboard加载NewFormView,直接用fatalError提示开发者使用正确的初始化方式即可;如果需要支持xib,你可能需要把viewModel改为可选类型,或者在awakeFromNib中补充初始化逻辑(但这种情况需要额外处理user的来源)。

使用方式

现在你就可以像预期的那样创建视图了:

let user = Users(/* 你的用户实例 */)
let newFormView = NewFormView(user: user)

内容的提问来源于stack exchange,提问作者J. Doe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:36:18