my grid is not updating properly my detail view

19 views Asked by At

supporting iOS 14, my problem is that THE FIRST TIME I tap on a cell, even if movie is valorized, no info is shown, after that, everything is working properly. Consider that when tapped on button, I print correctly info even first time. My view is in a tab but I don't think it is a problem. urls are not valorized since I'm testing what happens if my view is failing in downloading image.

import SwiftUI

struct Movie: Identifiable {
    let id = UUID().uuidString
    var title: String?
    var year: Int?
    var url: String?
}


//iniztialized inside entry point of the app
class ClassFromEntryPoint: ObservableObject {
    
    @Published var fromEntryPointValue = ""
    
    @Published var movies: [Movie] = []

    init() {

        movies.append(Movie(title: "Back to the future", year: 1985))
        movies.append(Movie(title: "Jaws", year: 1975))
        movies.append(Movie(title: "Start Wars", year: 1979))
    }
    
}
 




import SwiftUI
import Combine

class ImageLoader: ObservableObject {
    @Published var image: UIImage?
    private var cancellables = Set<AnyCancellable>()
    
    func load(fromURLString urlString: String) {
        guard let url = URL(string: urlString) else {
            return
        }
        URLSession.shared.dataTaskPublisher(for: url)
            .map { UIImage(data: $0.data) }
            .replaceError(with: nil)
            .receive(on: DispatchQueue.main)
            .sink { [weak self] in self?.image = $0 }
            .store(in: &cancellables)
    }
}

struct AsyncImageView: View {
    @StateObject private var loader = ImageLoader()
    let placeholderImage = Image(systemName: "photo")
    
    var url: String
    
    var body: some View {
        Group {
            if let image = loader.image {
                Image(uiImage: image)
                    .resizable()
            } else {
                placeholderImage
                    .resizable()
            }
        }
        .onAppear {
            loader.load(fromURLString: url)
        }
    }
}

struct FourthViewWithGrid: View {
    // Created inside an entry point of the app
    @EnvironmentObject var classFromEntryPoint: ClassFromEntryPoint
    
    @State private var movies: [Movie] = []
    @State private var selectedMovie: Movie?
    @State private var isShowingDetails = false
        
    let columns = [
        GridItem(.flexible()),
        GridItem(.flexible())
    ]
    
    var body: some View {
        NavigationView {
            ScrollView {
                LazyVGrid(columns: columns, spacing: 20) {
                    ForEach(movies) { movie in
                        Button(action: {
                            self.selectedMovie = movie
                            var _ = print("selected: \(movie)")
                            DispatchQueue.main.async {
                                self.isShowingDetails = true
                            }
                        }) {
                            VStack {
                               AsyncImageView(url: movie.url ?? "")
                                    .aspectRatio(contentMode: .fill)
                                    .frame(width: 100, height: 100)
                                    .cornerRadius(10)
                                
                                Text(movie.title ?? "ND/")
                                    .font(.headline)
                                    .lineLimit(1)
                                
                                if let year = movie.year {
                                    Text("\(year)")
                                        .font(.subheadline)
                                }
                            }
                        }
                    }
                }
                .padding()
            }
            .navigationTitle("Movies")
            .sheet(isPresented: $isShowingDetails) {
                // show details
                if let selectedMovie = selectedMovie {
                    Text(selectedMovie.title ?? "default title")
                } else {
                    var _ = print("no selected movie")
                    EmptyView()
                }
            }
        }
        .onAppear {
            movies = classFromEntryPoint.movies
        }
    }
}
0

There are 0 answers