I have a scenario where I need to show date picker and selected date in different format. Since SwiftUI's date picker shows date in a specific format after it's selected, I thought of opening date picker on a button click instead of directly using SwiftUI date picker, so I can display the date in desired format as button title. However, the date picker doesn't open over the list section within which the button resides.
Code:
import SwiftUIimport Foundationstruct ContentView: View { @State private var showSheet: Bool = false var body: some View { NavigationStack { VStack { Button { showSheet = true } label: { Text("Click Me").foregroundStyle(Color.blue) } } .navigationDestination(isPresented: $showSheet) { SampleSheet() } } }}struct SampleSheet: View { @State private var selectedDate = Date.now @State private var selectedPicker = "Day" @State private var dateLabelTitle = "Date" @State private var displayDate = "Mar 7, 2024" @State private var showDatePicker: Bool = false let segments = ["Day", "Week", "Month"] var body: some View { VStack { List { filterDateSection dateRangeSelectionSection } .environment(\.defaultMinListRowHeight, 0) .overlay { if showDatePicker { DatePicker("", selection: $selectedDate, displayedComponents: .date ) .labelsHidden() .datePickerStyle(.graphical) .zIndex(10) } } } } private var filterDateSection: some View { Section { HStack { // Default date picker works as expected.// DatePicker(selection: $selectedDate, displayedComponents: [.date]) {// Text("Date").font(.body).foregroundColor(Color.black)// } Text(dateLabelTitle).font(.body).foregroundStyle(Color.black) Spacer() Button { self.showDatePicker = true } label: { Text(displayDate).font(.body).foregroundStyle(Color.blue) } } .frame(height: 28.0) } header: { Text("Filter") } } private var dateRangeSelectionSection: some View { Section { Picker("Choose date selection range", selection: $selectedPicker) { ForEach(segments, id:\.self) { segment in Text(segment).tag(segment).font(.body) } } .pickerStyle(.segmented) .frame(width: UIScreen.main.bounds.width - 40.0, height: 38.0) .listRowInsets(EdgeInsets()) .background(Color.gray.opacity(0.3)) } header: { Text("Range") } }}
Currently, button label is showing today's date. But let's say I select March 10 in the date picker and set segmented control to "Week", then button label will be Mar 10, 2024 - Mar 17, 2024. I haven't added that logic yet, but my main issue is when date picker is opened via button click it doesn't lay over the list.
Left image is when date picker is opened via DatePicker(...) directly instead of button click. Right image is after executing my code I shared above.
How do I make my code to look like left image? I tried putting opening date picker code in overlay, but that didn't help.