我是编码的新手,这是我的第一个项目。我创建了一个应用程序,该应用程序可以根据胆固醇专家组实验室测试的数据确定心血管疾病(CVD)的风险。该应用程序可以在iPhone XR(画布模拟器)上正常运行。但是,当我在实际的iPhone XR设备上运行该应用程序时,它崩溃并产生以下消息:
Fatal Error: No ObservableObject of Type Data found. A View.environmentObject(_:) for Data
may be missing as an ancestor of this view.
在这里出现错误:
TextField("", text: $data.name)
.frame(width:350, height: 40)
.padding(.leading)
.background(Color.offWhite)
.foregroundColor(.fblue)
.cornerRadius(5)
.shadow(color: Color.black.opacity(0.4), radius: 5, x: 5, y: 5)
.shadow(color: Color.white.opacity(1.5), radius:5, x: -5, y: -5)
.font(.title)
.keyboardType(.alphabet)
我搜索了堆栈溢出(SO),并尝试了所有推荐的解决方案,但没有一个对我有用。我也在SO之外进行搜索,并进行了类似的尝试,并获得了相似的结果。我回到了SO,看看是否有人可以帮助我。根据这项研究,我认为我的ObservableObject在整个应用程序中都“可见”时存在问题,即使我一直遵循受人尊敬的编码人员和编码专家(SO贡献者,Paul Hudson,AzamSharp,Maxcodes,Brian Advent,与Chris一起编码等;)及其在构建我的应用程序过程中的类似示例。因此,我的问题是我用来引用ObservableObject的代码的语法,或者是我将引用代码放置在应用程序中的错误位置,或者缺少了一段代码,并且在我的任何研究中都从未提及过它。
该应用程序包含三个使用TextField,NavViews和NavLinks的用户输入视图。一个视图显示用户输入的结果,最后一个视图显示诊断和CVD的风险百分比。我在整个过程中都使用了@ EnvironmentObject,ObservableObject,@ Published var和@State private var。
以下是一些代码详细信息:(仅显示相关代码)
我的场景委托:
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene (_: UIScene, WillConnectTo session: UISceneSession, option connectingOptions:
UIScene.ConnectionOptions) {
//......
//......
let data = Data()
//....
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
// .....
// .....
let contentView = ContentView(
.environmentObject(data)
.environment(\.managedObjectContext, context)
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView.environmentObject(data))
self.window = window
window.makeKeyAndVisible()
}
}
func sceneDidDisconnect.......
我在ContentView中的类声明:
class Data: ObservableObject {
@Published var name = ""
@Published var age = ""
@Published var dob = ""
@Published var gender = ""
@Published var fast = ""
@Published var tc = ""
@Published var tg = ""
@Published var hdl = ""
@Published var ldl = ""
@Published var vldl = ""
@Published var apoB = ""
@Published var apoA1 = ""
@Published var apoRatio = ""
}
ResultsDiagnosticsView中的我的ResultsDiagnostics结构:
struct ResultsDiagnosticsView: View {
init() {
UITableView.appearance().tableFooterView = UIView()
UITableView.appearance().separatorStyle = .none
}
@EnvironmentObject var data: Data
@State private var name = ""
@State private var age = ""
@State private var dob = ""
@State private var selectedGender = ""
@State private var tc = ""
@State private var tg = ""
@State private var hdl = ""
@State private var ldl = ""
@State private var vldl = ""
@State private var apoB = ""
@State private var apoA1 = ""
var ptDOB: Double{
let patientDOB = Double(data.dob) ?? 0
return patientDOB
}
var ptTC: Double{
let patientTC = Double(data.tc) ?? 0
return patientTC
}
var ptTG: Double{
let patientTG = Double(data.tg) ?? 0
return patientTG
}
var ptHDL: Double{
let patientHDL = Double(data.hdl) ?? 0
return patientHDL
}
var ptLDL: Double{
let patientLDL = Double(data.ldl) ?? 0
return patientLDL
}
var ptVLDL: Double{
let patientVLDL = Double(data.vldl) ?? 0
return patientVLDL
}
var ptAPOB: Double{
let patientAPOB = Double(data.apoB) ?? 0
return patientAPOB
}
var ptAPOA1: Double{
let patientAPOA1 = Double(data.apoA1) ?? 0
return patientAPOA1
}
var ptAPOBA1: Double{
let patientAPOBA1 = ptAPOB/ptAPOA1
return patientAPOBA1
}
我的DiagnosticsRisk结构DiagnosticsRiskView:
struct DiagnosticsRiskView: View {
@EnvironmentObject var data: Data
@State private var name = ""
@State private var age = ""
@State private var dob = ""
@State private var selectedGender = ""
@State private var tc = ""
@State private var tg = ""
@State private var hdl = ""
@State private var ldl = ""
@State private var vldl = ""
@State private var apoB = ""
@State private var apoA1 = ""
var ptDOB: Double{
let patientDOB = Double(data.dob) ?? 0
return patientDOB
}
var ptTC: Double{
let patientTC = Double(data.tc) ?? 0
return patientTC
}
var ptTG: Double{
let patientTG = Double(data.tg) ?? 0
return patientTG
}
var ptHDL: Double{
let patientHDL = Double(data.hdl) ?? 0
return patientHDL
}
var ptLDL: Double{
let patientLDL = Double(data.ldl) ?? 0
return patientLDL
}
var ptVLDL: Double{
let patientVLDL = Double(data.vldl) ?? 0
return patientVLDL
}
var ptAPOB: Double{
let patientAPOB = Double(data.apoB) ?? 0
return patientAPOB
}
var ptAPOA1: Double{
let patientAPOA1 = Double(data.apoA1) ?? 0
return patientAPOA1
}
var ptAPOBA1: Double{
let patientAPOBA1 = ptAPOB/ptAPOA1
return patientAPOBA1
}
func progress() -> Double {
let j = (ptAPOBA1*3.43) - 0.099
let k = (j/(1+j)) * 100
let l = Double(round(10*k)/10)
return l
}
func setProgress()->CGFloat{
let temp = self.progress() / 2
return CGFloat(temp * 0.01)
}
我的NavView?NavLink for ResultsDiagnosticsView:
NavigationView {
VStack {
List{
Section(header: Text("Demographics").modifier(SectionMod())) {
HStack {
Text("Patient")
.modifier(Label())
Text(data.name)
.modifier(ResultText())
}.modifier(HStackMod())
.padding(.top, 10)
HStack {
HStack{
Text("Gender")
.modifier(Label())
Text(data.gender)
.modifier(ResultText())
}.modifier(HStackMod())
HStack{
Text("Fasting")
.modifier(Label())
Text(data.fast)
.modifier(ResultText())
}.modifier(HStackMod())
}
HStack {
Text("DOB ")
.modifier(Label())
Text(data.dob)
.modifier(ResultText())
}.modifier(HStackMod())
.padding(.bottom, 10)
}
Section(header: Text("Cholesterol/Triglycerides").modifier(SectionMod())) {
HStack{
Text("Cholesterol")
.modifier(Label())
Spacer()
.frame(width:115)
if ptTC < 200 {
Text("\(ptTC, specifier: "%.2f") N")
.modifier(Normal())
}else{
Text("\(ptTC, specifier: "%.2f") H")
.modifier(Abnormal())
}
}.modifier(HStackMod())
.padding(.top)
HStack{
Text("Triglycerides")
.modifier(Label())
Spacer()
.frame(width:115)
if ptTG < 100 {
Text("\(ptTG, specifier: "%.2f") N")
.modifier(Normal())
}else{
Text("\(ptTG, specifier: "%.2f") H")
.modifier(Abnormal())
}
}.modifier(HStackMod())
.padding(.bottom, 10)
}
Section(header: Text("Lipoproteins").modifier(SectionMod())) {
HStack{
Text("HDL")
.modifier(Label())
Spacer()
if ptHDL >= 50{
Text("\(ptHDL, specifier: "%.2f") N")
.modifier(Normal())
}else{
Text("\(ptHDL, specifier: "%.2f") L")
.modifier(Abnormal())
}
}.modifier(HStackMod())
.padding(.top, 10)
HStack{
Text("LDL")
.modifier(Label())
Spacer()
if ptLDL < 100{
Text("\(ptLDL, specifier: "%.2f") N")
.modifier(Normal())
}else{
Text("\(ptLDL, specifier: "%.2f") H")
.modifier(Abnormal())
}
}.modifier(HStackMod())
HStack{
Text("VLDL")
.modifier(Label())
Spacer()
if ptVLDL <= 30{
Text("\(ptVLDL, specifier: "%.2f") N")
.modifier(Normal())
}else{
Text("\(ptVLDL, specifier: "%.2f") H")
.modifier(Abnormal())
}
}.modifier(HStackMod())
.padding(.bottom, 10)
}
Section(header: Text("Apolipoproteins").modifier(SectionMod())) {
HStack{
Text("Apo B")
.modifier(Label())
Spacer()
if ptAPOB < 85 {
Text("\(ptAPOB, specifier: "%.2f") N")
.modifier(Normal())
}else{
Text("\(ptAPOB, specifier: "%.2f") H")
.modifier(Abnormal())
}
}.modifier(HStackMod())
.padding(.top)
HStack {
Text("Apo A1")
.modifier(Label())
Spacer()
if ptAPOA1 >= 135{
Text("\(ptAPOA1, specifier: "%.2f") N")
.modifier(Normal())
}else{
Text("\(ptAPOA1, specifier: "%.2f") L")
.modifier(Abnormal())
}
}.modifier(HStackMod())
HStack {
Text("Apo Ratio")
.modifier(Label())
Spacer()
if ptAPOBA1 < 0.63 {
Text("\(ptAPOBA1, specifier: "%.2f") N")
.modifier(Normal())
}else{
Text("\(ptAPOBA1, specifier: "%.2f ") H")
.modifier(Abnormal())
}
}.modifier(HStackMod())
}
}
HStack{
NavigationLink(destination: TCTGView().navigationBarTitle("")
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)) {
Text("Start Over")
.fontWeight(.bold)
.font(.subheadline)
.padding()
.background(Color.fblue)//
.foregroundColor(.white)
.cornerRadius(10)
.shadow(color: Color.black.opacity(0.4), radius: 5, x: 5, y: 5)
.shadow(color: Color.white.opacity(1.5), radius:5, x: -5, y: -5)
}
NavigationLink(destination: ApolipoproteinsView().navigationBarTitle("")
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)) {
Text("Back")
.fontWeight(.bold)
.font(.subheadline)
.padding()
.background(Color.fblue)
.foregroundColor(.white)
.cornerRadius(10)
.shadow(color: Color.black.opacity(0.4), radius: 5, x: 5, y: 5)
.shadow(color: Color.white.opacity(1.5), radius:5, x: -5, y: -5)
}
NavigationLink(destination: DiagnosticsRiskView().navigationBarTitle("")
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)) {
Text("Next")
.fontWeight(.bold)
.font(.subheadline)
.padding()
.background(Color.fblue)
.foregroundColor(.white)
.cornerRadius(10)
.shadow(color: Color.black.opacity(0.4), radius: 5, x: 5, y: 5)
.shadow(color: Color.white.opacity(1.5), radius:5, x: -5, y: -5)
}
}.padding(.bottom, 80)
}
}.edgesIgnoringSafeArea(.top)
如果该应用程序的完整副本会有所帮助,请发电子邮件给我(wcmarrocco@gmail.com),因为我不知道如何在此处嵌入我的项目的副本。谢谢!
答案 0 :(得分:0)
在您的ResultsDiagnosticsView
顶部添加ObservalObject,然后通过添加...将其手动推到NavigationsLinks中。
NavigationLink(destination: TCTGView().environmentObject(self.data)