SwiftUI Handling User Input Guide Troubles

Hi,

Hopefully someone can point me in the right direction as I’m tearing my hair out with this one! I’m following the Handling User Input guide produced by Apple for SwiftUI. I’ve followed Chris’s video but I still can’t work out were I have gone wrong.

The app loads and build and appears to function correctly but my button to toggle the favorite status doesn’t save the change. I can see the state change on the location detail screen but when I return to the list view, the update of the isFavorite property hasn’t saved.

Has anyone else seen this issue? This is 20 minute guide apparantly and i’m on about 8 hours so far :unamused:

Thanks!

1 Like

you might need to provide us your code for this. at least for the part where you save favorites and display the data

Hi,

Thanks for the reply @fuerte.francis ,here is some of the snippets…

UserData swift file:

import Foundation
import SwiftUI
import Combine

final class UserData: ObservableObject {

@Published var showFavoritesOnly = false
@Published var landmarks = landmarkData

}

LandmarkDetail code:

struct LandmarkDetail: View {

@EnvironmentObject var userData: UserData
var landmark: Landmark

var landmarkIndex: Int {
    userData.landmarks.firstIndex(where: { $0.id == landmark.id })!
}

var body: some View {
    VStack {
        MapView(coordinate: landmark.locationCoordinate)
            .frame(height: 300)

        CircleImage(image: landmark.image)
            .offset(x: 0, y: -130)
            .padding(.bottom, -130)

        VStack(alignment: .leading) {
            HStack {
            Text(landmark.name)
                .font(.title)
                
                Button(action: {
                    
                    self.userData.landmarks[self.landmarkIndex]
                        .isFavorite.toggle()})
                {
                if self.userData.landmarks[self.landmarkIndex].isFavorite {
                        Image(systemName: "star.fill")
                            .foregroundColor(Color.yellow)
                    }
                        else {
                        Image(systemName: "star")
                            .foregroundColor(Color.gray)
                    }
                }

I’m sure it is something really obvious but right now, I can’t see it.

Thanks

Ian

how about the codes for listing?

@fuerte.francis, sure, here it is…

@EnvironmentObject var userData: UserData

var body: some View {
    NavigationView {
        
        List {

            Toggle(isOn: $userData.showFavoritesOnly) {
                Text("Show Favorites")
            }
            
            ForEach(landmarkData) { landmark in
                if !self.userData.showFavoritesOnly || landmark.isFavorite {
                    
                    NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
                        LandmarkRow(landmark: landmark)
                            }
                        }
                }
        }
        .navigationBarTitle(Text("Landmarks"))
    }
}

}

struct LandmarkList_Previews: PreviewProvider {
static var previews: some View {

    LandmarkList()
        .environmentObject(UserData())
}

}

1 Like

I found the publishing and subscribing and bindings very confusing in the first place and then I am having am the same error you have plus the previews don’t like the environmentObject() anymore when I use the @ObservedObject instead of @EnvironmentObject in the userData declarations in List and Detail pages. So frustrating that Swift keeps changing their code. :unamused: :face_with_symbols_over_mouth:
Event declarations and triggers suck in any language. This reminds me of C#'s old way to declare an event and then you have to call a delegate at some point to pass along the data to the event call. Most complicated mess I ever did see.

I went through the apple documentation and made sure I had their exact code and now it works. I don’t completely understand how its working but its working now shrug