Search code examples
iosasynchronousswiftuiswiftui-sheet

My SwiftUI app does not dynamically populate the content of a pop-up View when the first button is pressed


I have a grid of small images/icons as buttons and a pop-up modal View. The modal view is meant to display a larger version of the image that was the button, and some information about it. However, in practice, the first button pressed just brings up an empty View. Only after closing it and pressing a different button is the view populated. From that point forward, the app works as expected. I assume it's because of the asynchronous nature of the sheet modifier, but I can't seem to get a handle on how to populate the modal View before it is displayed the first time.

Here is a drastically simplified version of the code (with two simple text buttons) that exhibits the same behavior, so you can see what I'm doing.

import SwiftUI

struct ContentView: View {
    @State private var showModal = false
    @State private var selectedItem = ""
    
    var body: some View {
        VStack {
            Button(action: {
                self.selectedItem = "Button 1"
                self.showModal = true
            }) {
                Text("Button 1")
            }
            Button(action: {
                self.selectedItem = "Button 2"
                self.showModal = true
            }) {
                Text("Button 2")
            }
        }
        .sheet(isPresented: $showModal, content: {
            ModalView(item: self.selectedItem)
        })
    }
}

struct ModalView: View {
    let item: String
    
    var body: some View {
        VStack {
            Text("You pushed \(item)")
        }
    }
}

In this circumstance, if I tap "Button 1", it just opens a view that just says "You pushed ". If I close that modal and tap it again, the same thing happens. Only when I tap "Button 2" does the modal view pop up and say "You pushed Button 2" and after that point, it also says "You pushed Button 1" when I tap "Button 1".


Solution

  • try using

    @State private var selectedItem: String? 
    

    and

    .sheet(item: $selectedItem){ item in 
         ModalView(item: item)
     } 
    

    instead. No need for showModal