SwiftUI项目中Sheet调用视图报错及诊断失败问题求助
SwiftUI项目错误排查:Sheet调用与视图初始化问题
这是我的第一个SwiftUI项目,现有如下视图代码:
import SwiftUI struct RosaView: View { @State var rosa: [Rosa] = Rosa.testRosa() @State private var apriNuovoGiocatore = false @State var stagione: String = "2023/2024" var rosaFiltrata: [Rosa] { Rosa.testRosa().filter { $0.stagione == stagione } } @State private var selezioneGiocatore: Rosa.ID? = nil @State private var ordine = [KeyPathComparator(\Rosa.ruoloGiocatore)] var body: some View { VStack(alignment: .leading) { Text("Stagione: \(stagione)") .fontWeight(.bold) .font(.headline) .foregroundColor(.blue) .padding() Table(rosaFiltrata, selection: $selezioneGiocatore, sortOrder: $ordine) { TableColumn(Text("Nome").foregroundStyle(.blue), value: \.nomeGiocatore) TableColumn(Text("Cognome").foregroundStyle(.blue), value: \.cognomeGiocatore) TableColumn(Text("Ruolo").foregroundStyle(.blue), value: \.ruoloGiocatore) TableColumn(Text("Data di nascita").foregroundStyle(.blue), value: \.nascitaGiocatore) TableColumn(Text("Età").foregroundStyle(.blue)) { rosa in Text("\(rosa.etàGiocatore)") } } } .frame(width: 900, height: 400) .toolbar { Button { apriNuovoGiocatore = true } label: { Image(systemName: "person.badge.plus") .foregroundColor(.blue) } .sheet(isPresented: $apriNuovoGiocatore, content: { nuovoGiocatore() }) } .navigationTitle("Rosa") } } struct nuovoGiocatore: View { @Environment(\.dismiss) var dismiss @State var nomeNuovoGiocatore: String @State var cognomeNuovoGiocatore: String @State var nascitaNuovoGiocatore: String @State var ruoloNuovoGiocatore: String @State var etàNuovoGiocatore: Int var body: some View { NavigationStack { Form { TextField("Nome:", text: $nomeNuovoGiocatore) TextField("Cognome:", text: $cognomeNuovoGiocatore) } .navigationTitle("Nuovo giocatore") .toolbar { Button("Cancel") { dismiss() } Button("Aggiungi giocatore") { let nuovoGiocatore = Rosa(stagione: "2023/2024", nomeGiocatore: nomeNuovoGiocatore, cognomeGiocatore: cognomeNuovoGiocatore, nascitaGiocatore: nascitaNuovoGiocatore, etàGiocatore: etàNuovoGiocatore, ruoloGiocatore: ruoloNuovoGiocatore) Rosa.testRosa().append(nuovoGiocatore) dismiss() } } } } } #Preview { RosaView() }
目前遇到两个异常错误:
- 在Sheet中调用
nuovoGiocatore()时,提示“Missing arguments for parameters 'nomeNuovoGiocatore', 'cognomeNuovoGiocatore', 'nascitaNuovoGiocatore', 'ruoloNuovoGiocatore', 'etàNuovoGiocatore' in call”; - 在
nuovoGiocatore视图中出现“Failed to produce diagnostic for expression; please submit a bug report”错误。
错误原因及修复方案
1. Sheet调用时的参数缺失错误
nuovoGiocatore作为结构体视图,所有@State属性未设置默认值,Swift要求结构体初始化时必须为所有存储属性赋值,因此直接调用nuovoGiocatore()会因参数缺失报错。
修复:给每个@State属性添加默认值,同时遵循Swift命名规范将视图名改为首字母大写(避免与变量混淆):
struct NuovoGiocatoreView: View { @Environment(\.dismiss) var dismiss // 为@State属性设置默认值 @State var nomeNuovoGiocatore: String = "" @State var cognomeNuovoGiocatore: String = "" @State var nascitaNuovoGiocatore: String = "" @State var ruoloNuovoGiocatore: String = "" @State var etàNuovoGiocatore: Int = 0 // 其余代码不变 }
同步修改Sheet中的调用:
.sheet(isPresented: $apriNuovoGiocatore, content: { NuovoGiocatoreView() })
2. 无法生成诊断信息的错误
该错误是第一个错误引发的连锁问题,Swift编译器在处理参数缺失类错误时,偶尔会抛出此类模糊提示,修复第一个错误后,该提示会自动消失。
额外逻辑问题修复
除上述错误外,代码还有两处逻辑缺陷:
- 过滤数组使用临时数据:
rosaFiltrata中每次调用Rosa.testRosa()都会生成新临时数组,应使用@State中的rosa数组,确保添加新球员后视图自动更新:
var rosaFiltrata: [Rosa] { rosa.filter { $0.stagione == stagione } }
- 添加球员未修改原数组:
Rosa.testRosa().append(nuovoGiocatore)仅操作临时数组,不会更新RosaView中的@State var rosa,可通过闭包回调传递新球员:
// 修改NuovoGiocatoreView,添加回调闭包 struct NuovoGiocatoreView: View { @Environment(\.dismiss) var dismiss @State var nomeNuovoGiocatore: String = "" @State var cognomeNuovoGiocatore: String = "" @State var nascitaNuovoGiocatore: String = "" @State var ruoloNuovoGiocatore: String = "" @State var etàNuovoGiocatore: Int = 0 // 新增回调闭包,用于传递新创建的球员 var onAddGiocatore: (Rosa) -> Void var body: some View { // 其余代码不变 Button("Aggiungi giocatore") { let nuovoGiocatore = Rosa(stagione: "2023/2024", nomeGiocatore: nomeNuovoGiocatore, cognomeGiocatore: cognomeNuovoGiocatore, nascitaGiocatore: nascitaNuovoGiocatore, etàGiocatore: etàNuovoGiocatore, ruoloGiocatore: ruoloNuovoGiocatore) onAddGiocatore(nuovoGiocatore) dismiss() } } }
修改Sheet调用时传递闭包:
.sheet(isPresented: $apriNuovoGiocatore, content: { NuovoGiocatoreView { nuovoGiocatore in rosa.append(nuovoGiocatore) } })
内容的提问来源于stack exchange,提问作者AndreB82
相关产品推荐
相关产品推荐

