I use my @EnvironmentObject
to let my TeamData can use by different but it doesn't work well. When I go to another view by navigationLink in List, it's fine. When I tap a button to the same View, it crashed..
I think I put something wrong. Can somebody help for this issue? Is it mean I need to add @EnvironmentObject
at the NavigationView first so that I can use it? Thanks
Demo: https://youtu.be/-iRadrHd94c
import SwiftUI
struct GameRecordListView: View {
@EnvironmentObject var teamResult : TeamResult
@State var hint : String = ""
@State var successRegistration : Bool = false
@State var sheetPresented: Bool = false
var body: some View {
VStack{
List(0 ..< 12){ item in
NavigationLink(destination: GameDetailRecordView()){ <-this works well
Text("444")
}
}
VStack{
Spacer()
HStack{
Spacer()
NavigationLink(destination: GameDetailRecordView()) <-this doesn't works well and crashed
{
Image(systemName: "pencil.circle")
.resizable()
.frame(width: 35, height: 35)
.padding(12)
.background(Color.blue)
.foregroundColor(Color.white)
.clipShape(Circle())
}
}.padding(15)
}
}.onAppear(perform: {
print("teamResult:\(self.teamResult.groupID):\(self.teamResult.groupName)")
})
}
}
I create a enviromentObject in this View
import SwiftUI
import SwiftyJSON
struct TeamDetail: View {
@EnvironmentObject var teamResult : TeamResult
// @ObservedObject var teamResult: TeamResult
var roles = ["GameRecord", "Schedule", "Money", "Member"]
@State var show = false
@State private var selectedIndex = 0
var body: some View {
ZStack{
VStack {
Picker(selection: $selectedIndex, label: Text("")) {
ForEach(0..<roles.count) { (index) in
Text(self.roles[index])
}
}
.pickerStyle(SegmentedPickerStyle())
HStack{
containedView()
}
Spacer()
}
}.navigationBarTitle(teamResult.groupName)
.onAppear(perform:{
})
}
//select different view by selectedIndex
func containedView() -> AnyView {
switch selectedIndex {
case 0:
return AnyView(
GameRecordListView().environmentObject(teamResult) <-create environmentObject here
)
case 1:
return AnyView(Text("")
.padding(30))
case 2:
return AnyView(
BookkeepingView().environmentObject(teamResult)
)
default:
return AnyView(
TeamMemberListView().environmentObject(teamResult))
}
}
}
The view I use the @EnviromentObject
import SwiftUI
struct GameDetailRecordView: View {
@EnvironmentObject var teamResult : TeamResult
var body: some View {
Text("ID:\(teamResult.groupID)Name:\(teamResult.groupName)")
}
}
Error message:
Fatal error: No ObservableObject of type TeamResult found.
A View.environmentObject(_:) for TeamResult may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-39.4.3/Core/EnvironmentObject.swift, line 55
2020-01-20 01:14:58.466655+0800 Fitness(SwiftUI)[49035:4851345] Fatal error: No ObservableObject of type TeamResult found.
A View.environmentObject(_:) for TeamResult may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-39.4.3/Core/EnvironmentObject.swift, line 55
The way @EnvironmentObject works is when called within a view, it looks from an object of that type in the environment (in other words, from any parent above it that has specified an environmentObject ), and then lets you use it.
An environment object invalidates the current view whenever the observable object changes. If you declare a property as an environment object, be sure to set a corresponding model object on an ancestor view by calling its environmentObject (_:) modifier.
If you have a data model object that you want to use throughout your app, but don’t want to pass it through many layers of hierarchy, you can use the environmentObject (_:) view modifier to put the object into the environment instead:
Think of @EnvironmentObject as a smarter, simpler way of using @ObservedObject on lots of views. Rather than creating some data in view A, then passing it to view B, then view C, then view D before finally using it, you can create it in view A and put it into the environment so that views B, C, and D will automatically have access to it.
try adding environmentObject on the view in the NavigationLink
NavigationLink(destination: GameDetailRecordView().environmentObject(teamResult))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With