SwiftUI中子视图如何设置私有状态变量?跨视图传值报错解决方案
问题原因分析
- 核心报错来自第二个视图
kek的属性未正确初始化:你声明了@State var Question : String但没有给初始值,也没有自定义构造方法接收该参数,Swift自动生成的构造器要求必须传入所有未初始化的属性,你当前调用kek(One: multiplicationTable, Two: amountQuestions)时缺少Question参数,所谓的「无法传递私有变量」是构造器不匹配产生的衍生错误提示。 - 补充说明:
ContentView里的@State private变量只是限制当前视图内部访问修改,将其值作为普通参数传递给下一个视图的存储属性是完全合法的,不会引发传值错误。
修复方案
- 给
kek视图中未初始化的@State属性添加默认值,同时在视图加载时调用nextQuestion生成第一道题目,同时调整命名符合Swift开发规范:
import SwiftUI // 类型名首字母大写 struct Kek: View { // 属性名首字母小写,语义清晰 let selectedTable: Int let questionCount: Int // 给状态属性设置默认值 @State private var currentQuestion = "" @State private var answer = "" @State private var factor1 = 0 @State private var factor2 = 0 func nextQuestion(){ factor1 = selectedTable factor2 = Int.random(in: 0...10) currentQuestion = "\(factor1) * \(factor2)" } var body: some View { VStack { Text("Question: What is \(currentQuestion)?") Form { Section { TextField("Enter answer", text: $answer) .keyboardType(.decimalPad) } } Button ("Next") { nextQuestion() answer = "" } .padding(50) .background(Color.red) .foregroundColor(.white) .clipShape(Circle()) } // 视图加载时自动生成第一道题 .onAppear { nextQuestion() } } } struct Kek_Previews: PreviewProvider { static var previews: some View { Kek(selectedTable: 1, questionCount: 2) } }
- 修改
ContentView中的冗余代码,移除NavigationLink中嵌套的多余Button,修正数组命名笔误:
import SwiftUI struct ContentView: View { @State private var multiplicationTable = 1 @State private var amountQuestions = 1 let multiplicationTables = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // 修正原命名多打s的笔误 let amountQuestionsArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] var body: some View { // iOS16+推荐用NavigationStack替代已废弃的NavigationView NavigationStack { VStack { Picker(selection: $multiplicationTable, label: Text("Choose multiplication table")) { // 直接遍历数组元素避免索引越界风险 ForEach(multiplicationTables, id: \.self) { table in Text("\(table)") } } .padding(.vertical, 32) Text("Choose number of Questions") Picker("Select number of questions", selection: $amountQuestions) { ForEach(amountQuestionsArray, id: \.self) { count in Text("\(count)") } } // 移除多余的Button嵌套,NavigationLink本身支持点击交互 NavigationLink(destination: Kek(selectedTable: multiplicationTable, questionCount: amountQuestions) .navigationBarHidden(true)) { Text("GO") .padding(50) .background(Color.red) .foregroundColor(.white) .clipShape(Circle()) } .navigationTitle("Choose Multiplication Table") .navigationBarTitleDisplayMode(.inline) } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
内容的提问来源于stack exchange,提问作者Charlie Tan
相关产品推荐
相关产品推荐

