'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:
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 |
|---|

