'SwiftUI Bizarre Picker Behavior with Modal Sheets

I'm experiencing a truly bizarre behavior with an app that has pickers in a view that calls a map as a sheet modal. The pickers are not directly involved in calling the map - but set conditions for the annotations that will be displayed. And in the simple example I have included below, it is clear the issue has nothing to do with the map - the problem behavior is present with a simple text view in the modal.

The issue: if the user swipes to dismiss the modal it appears to always work as expected. If the user taps a button to dismiss the modal with either the environment dismiss or through a binding to the @State that calls the view, then after the second showing of the modal, you can no longer raise the picker - the displayed value just turns color - as if a color toggle on tap. I've also tried showing the modal as full screen, as an animation and as a transition. I get the same result every time. I'm at the point where I think this must be an Xcode bug, but I hope someone can show me a solution. The same behavior exists in Preview, Simulator and a real Device.

Here is a very stripped down example which demonstrates the issue:

enum StorageKeys: String {
    case appChosenFuel, appChosenState
}//enum

struct ContentView: View {

    @State private var showGroupMapView: Bool = false
    @State private var showTooBigAlert: Bool = false
    @State private var justANumber: Int = 500

    var body: some View {
        NavigationView {
            VStack {
                Text("Picker plus Sheet Test")
                    .padding()
                FuelPickerView()
            }
            .toolbar {
                ToolbarItemGroup(placement: .navigationBarTrailing) {
                    Button {
                        if justANumber > 1000 {
                            showTooBigAlert = true
                        } else {
                            withAnimation {
                                showGroupMapView.toggle()
                            }
                        }
                    } label: {
                        Image(systemName: "map")
                            .font(.system(size: 20))
                            .frame(width: 40, height: 40)
                    }
                    .sheet(isPresented: $showGroupMapView, onDismiss: {
                        print("you dismissed me")
                    }) {
                        GroupMapView()
                    }
                }//toolbar group
            }//toolbar
        }//nav
    }//body
}//sruct

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct GroupMapView: View {

    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        ZStack {
            Text("This is the map view")
            VStack {
                HStack {
                    Spacer()
                    Button {
                        presentationMode.wrappedValue.dismiss()
                    } label: {
                        Image(systemName: "gear")
                            .padding(.trailing, 20)
                            .padding(.top, 20)
                    }
                }
                Spacer()
            }
        }//z
    }
}//struct

class FuelPickerViewModel: ObservableObject {

    struct FuelItem: Identifiable, Hashable {
        let id = UUID()
        let name: String
        let initials: String
    }

    @Published var fuelItems = [
        FuelItem(name: "Biodiesel (B20 and above)", initials: "BD"),
        FuelItem(name: "Compressed Natural Gas", initials: "CNG"),
        FuelItem(name: "Ethanol (E85)", initials: "E85"),
        FuelItem(name: "Electric", initials: "ELEC"),
        FuelItem(name: "Hydrogen", initials: "HY"),
        FuelItem(name: "Liquified Natural Gas", initials: "LNG"),
        FuelItem(name: "Liquified Petroleum Gas (Propane)", initials: "LPG")
    ]
}//class

struct FuelPickerView: View {

    @AppStorage(StorageKeys.appChosenFuel.rawValue) var appChosenFuel = "ELEC"
    @AppStorage(StorageKeys.appChosenState.rawValue) var appChosenState = "CO"

    @StateObject var fuelPickerVM = FuelPickerViewModel()

    var body: some View {
        return VStack {
            Picker("Fuel", selection: $appChosenFuel) {
                ForEach(fuelPickerVM.fuelItems, id: \.self) {
                    Text($0.initials)
                }
            }
        }
    }//body
}//struct

And after the second modal display/dismiss with the button, tapping the picker does nothing except change the background color:

enter image description here

Any guidance would be appreciated: Xcode 13.2.1 iOS 15.2



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source