SwiftUI导航链接跳转DetailView报错的解决方案咨询
问题描述
我想让ContentView中的调查列表点击导航链接时打开DetailView,但一直报错:Missing argument for parameter 'newsurvey' in call Insert 'newsurvey: <#Survey#>'
主页ContentView代码
struct ContentView: View { @State var surveys: [Survey] = [] @State var isPresented = false @State var selectedTab: Int = 0 @State private var path = [String]() let dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "MM/dd/yyyy" return formatter }() var body: some View { ZStack { VStack{ NavigationView { VStack { Text("") .frame(height: 0) .navigationBarTitleDisplayMode(.inline) //reduces navbartitle height .toolbar { ToolbarItem(placement: .principal) { Image("RR_Logo_Primary_Full_Color") .resizable() .frame(width: 275.0, height: 55.0) } } List(surveys) { survey in NavigationLink(destination: DetailView(newsurvey: survey)) //must be within navigationview { HStack{ ZStack { Rectangle() .frame(width: 400, height: 100.0) .foregroundColor(.white) .cornerRadius(4) HStack (alignment: .top) { VStack (alignment: .leading) { Text(survey.customerName) .offset(x: -60, y: -2) .font(.custom("Roboto-Light", size: 24)) Text(survey.lineName) .offset(x: -60, y: -5) .font(.custom("Roboto-Light", size: 18)) Text("# of conveyors") .offset(x: -60) } VStack { Text(dateFormatter.string(from: survey.date)) .font(.custom("Roboto-Light", size: 18)) .offset(x: 60) } } } } } } .listRowInsets(EdgeInsets()) } } .environment(\.defaultMinListHeaderHeight, 1) CustomTabBar(surveys: $surveys, isPresented: $isPresented) .frame(height: 60, alignment: .bottom) } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
尝试的DetailView代码(出现"not in scope"错误)
struct DetailView: View { @State var newsurvey: Survey @State var surveys: [Survey] = [] @State private var conveyorName = "" @State private var masterTag = "" @State private var showAddConveyorSheet = false @State private var conveyors: [Conveyor] = [] var body: some View { NavigationView { VStack { List { ForEach(conveyors, id: \.name) { conveyor in NavigationLink(destination: ConveyorTrack(conveyor: conveyor)) { Text(conveyor.name) } } } Button(action: { self.showAddConveyorSheet = true }) { Text("Add Conveyor") } } .navigationBarTitle("Conveyors", displayMode: .inline) .sheet(isPresented: $showAddConveyorSheet) { VStack { HStack { TextField("Conveyor Name", text: $conveyorName) TextField("Master Tag", text: $masterTag) .onTapGesture { // open camera and scan text here } } Button(action: { self.conveyors.append(Conveyor(id: self.conveyorName, name: self.conveyorName, masterTag: self.masterTag)) self.conveyorName = "" self.masterTag = "" self.showAddConveyorSheet = false }) { Text("Save") } } } } } } struct DetailView_Previews: PreviewProvider { static var previews: some View { DetailView(newsurvey: survey) } }
解决方案
错误拆解
- 参数传递不匹配:ContentView中调用
DetailView(newsurvey: survey)报错,核心原因是DetailView对传入参数的声明不规范,且预览代码中未定义可用的Survey实例。 - 状态滥用:
DetailView中用@State修饰传入的newsurvey是错误的——父视图传入的数据不需要作为可变状态,用常量即可。 - 预览变量未定义:
DetailView_Previews中的survey变量未初始化,导致"not in scope"错误。
修正代码
1. 重构DetailView的参数声明
struct DetailView: View { // 用常量接收父视图传入的survey,无需@State let newsurvey: Survey // 仅保留需要本地修改的状态 @State private var conveyorName = "" @State private var masterTag = "" @State private var showAddConveyorSheet = false @State private var conveyors: [Conveyor] = [] var body: some View { NavigationView { VStack { List { ForEach(conveyors, id: \.name) { conveyor in NavigationLink(destination: ConveyorTrack(conveyor: conveyor)) { Text(conveyor.name) } } } Button(action: { showAddConveyorSheet = true }) { Text("Add Conveyor") } } .navigationBarTitle("Conveyors", displayMode: .inline) .sheet(isPresented: $showAddConveyorSheet) { VStack { HStack { TextField("Conveyor Name", text: $conveyorName) TextField("Master Tag", text: $masterTag) .onTapGesture { // 扫码逻辑实现 } } Button(action: { let newConveyor = Conveyor(id: conveyorName, name: conveyorName, masterTag: masterTag) conveyors.append(newConveyor) conveyorName = "" masterTag = "" showAddConveyorSheet = false }) { Text("Save") } } } } } }
2. 修复预览代码
创建测试用的Survey实例传入预览:
struct DetailView_Previews: PreviewProvider { static var previews: some View { // 构造测试用Survey实例,补充结构体所需的所有属性 let testSurvey = Survey( customerName: "测试客户", lineName: "测试生产线", date: Date(), conveyors: [] ) DetailView(newsurvey: testSurvey) } }
3. 确保数据结构体遵循Identifiable协议
ContentView中的List要求数据源遵循Identifiable,补充协议实现:
struct Survey: Identifiable { let id = UUID() var customerName: String var lineName: String var date: Date var conveyors: [Conveyor] // 补充Survey的其他必要属性 } struct Conveyor: Identifiable { let id: String var name: String var masterTag: String // 补充Conveyor的其他必要属性 }
内容的提问来源于stack exchange,提问作者Isaac Vasquez
相关产品推荐
相关产品推荐

