I've had issues updating the Home View of my app using SwiftUI.
So, I have a Dog struct ( Dog.swift ) :
struct Dog: Identifiable {
var id = UUID()
var name: String
var race: String
var age: Int
var gender: String
var sterile: Bool
var pictureURL: String
var location: String
var dogFriendly: Bool
var catFriendly: Bool
var childFriendly: Bool
var needsGarden: Bool
var isClean: Bool
}
My goal is to press this Button inside AddView.swift :
@ObservedObject var viewModel = AddViewModel()
************** LONG UI CODE *******************
.navigationBarItems(trailing:
Button("Publish") {
viewModel.dogs.append(Dog(name: self.name, race: races[selectedRace], age: self.age, gender: genders[selectedGender], sterile: self.isSterile, pictureURL: "", location: "", dogFriendly: self.isDogFriendly, catFriendly: self.isCatFriendly, childFriendly: self.isChildFriendly, needsGarden: self.needsGarden, isClean: self.isClean))
print(viewModel.dogs)
})
to append dogs to the Dog array inside AddViewModel.swift :
class AddViewModel: ObservableObject {
@Published var dogs: [Dog] = []
}
and then show the information in a CardView:
struct CardView: View {
//MARK: - Properties
@State var dog: Dog
//MARK: - View
var body: some View {
******* LONG UI CODE ********
}
and display those CardView in my HomeView:
struct HomeView: View {
@ObservedObject var viewModel = AddViewModel()
var body: some View {
ScrollView {
VStack {
ForEach(viewModel.dogs) { dog in
CardView(dog: dog) // this doesn't work
Text(dog.name) // this doesn't work neither
}
}
}
}
}
Can someone help me about it and give me an advice on how to proceed?
Thank you for your generous help!
Change @State to @Bindig will fix it.
CardView:
struct CardView: View {
//MARK: - Properties
@Binding var dog: Dog
//MARK: - View
var body: some View {
******* LONG UI CODE ********
}
I think you want to append Array
of Dog
inside AddView
and show the updated data inside HomeView
. So, you just declared an instance of AddViewModel
inside each view separately. The both instances inside views don't not observe each other. To get around this, I prefer to use Singleton
pattern. Here is my sample code.
struct ContentView: View {
@ObservedObject private var viewModel: AddViewModel = .sharedInstance
@State private var showSheet = false
var body: some View {
NavigationView {
ScrollView {
ForEach(viewModel.dogs) { dog in
Text(dog.name)
.frame(height: 25)
}
}
.navigationTitle("DogZ")
.navigationBarItems(leading: Button(action: {
showSheet.toggle()
}, label: {
Text("Show")
}))
}
.sheet(isPresented: $showSheet, content: {
AddView()
})
}
}
struct AddView: View {
@ObservedObject private var viewModel: AddViewModel = .sharedInstance
@Environment(\.presentationMode) var presentationMode
var body: some View {
NavigationView {
Text("Sheet Add View")
.navigationBarItems(trailing: Button(action: {
viewModel.dogs.append(Dog(name: "Blacky"))
presentationMode.wrappedValue.dismiss()
}, label: {
Text("Add")
}))
}
}
}
class AddViewModel: ObservableObject {
@Published var dogs = [Dog]()
static var sharedInstance = AddViewModel()
}
struct Dog: Identifiable {
var id = UUID()
var name: String
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.