Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@EnvironmentObject doesn't work well through navigationLink

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
like image 658
frank61003 Avatar asked Jan 19 '20 17:01

frank61003


People also ask

How to use @environmentobject in a view?

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.

What happens when an environment object invalidates the current view?

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.

How do I put a data model object in the environment?

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:

What is @environmentobject in Salesforce?

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.


1 Answers

try adding environmentObject on the view in the NavigationLink

 NavigationLink(destination: GameDetailRecordView().environmentObject(teamResult))
like image 99
Kenny Kurochkin Avatar answered Oct 11 '22 18:10

Kenny Kurochkin