SwiftUI子父视图传值时,子视图初始化器未初始化所有存储属性问题
解决SwiftUI子视图初始化未完成所有存储属性的错误
问题原因
你定义的子视图Child(或父视图中调用的OneColumnList)包含三个存储属性:changeStage、icons、options,但自定义的初始化方法只初始化了icons和options,遗漏了changeStage,这就导致编译器抛出Return from initializer without initializing all stored properties错误。
两种解决方案
方案1:修改自定义初始化方法,添加changeStage参数
在子视图的初始化方法中加入changeStage参数,同时因为这个闭包会在初始化完成后才被调用(比如用户交互触发),需要给闭包加上@escaping关键字:
struct Child: View { var changeStage: (Int) -> () var icons: [String] var options: [String] init(changeStage: @escaping (Int) -> (), icons: [String], options: [String]) { self.changeStage = changeStage self.icons = icons self.options = options } var body: some View { // 示例:通过按钮触发回调向父视图传值 Button("切换阶段") { changeStage(1) // 向父视图传递Int类型数据 } } }
父视图的调用代码无需修改,因为你已经在传递changeStage参数了。
方案2:移除自定义初始化方法,使用自动生成的成员初始化器
如果不需要自定义初始化逻辑,可以直接删掉子视图中的init方法,Swift会自动生成包含所有属性的成员初始化器,这样父视图的调用代码依然有效:
struct Child: View { var changeStage: (Int) -> () var icons: [String] var options: [String] var body: some View { Button("切换阶段") { changeStage(2) } } }
注意点
- 注意父视图中调用的
OneColumnList和你定义的子视图Child名称不一致,确保实际代码中名称统一,避免额外的错误。 @escaping关键字是必须的,因为闭包changeStage会逃逸出初始化方法的执行范围,在子视图的后续生命周期中被调用。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

