In iOS 17, you could use .opacity(0.011)
, .contentShape(Rectangle())
, and .allowsHitTesting(true)
on a hidden DatePicker
to capture taps and trigger the default DatePicker presentation (the “popup”).
In iOS 18, SwiftUI DatePicker no longer responds to taps if it’s fully transparent or minimally visible (especially when opacity
is too low).
iOS 18 requires the DatePicker to be "interactable" in a normal, non-hacky way. Otherwise, the system won’t "lift" the control and present the date selection UI.
In your code:
DatePicker(selection: $viewModel.selectedDate, displayedComponents: .date) {} .labelsHidden() .allowsHitTesting(true) .contentShape(Rectangle()) .opacity(0.011) // <--- making it almost invisible
That .opacity(0.011)
is now a blocker in iOS 18.
Commenting it out, you said, brings back the date picker UI — because the system now requires a visibly interactive surface.
.opacity(0.01)
but wrap inside a buttonInstead of hacking opacity directly, you control the date picker manually.
You can create a .sheet
or .popover
when the user taps the text.
Example:
struct ContentViewA: View {
@StateObject var viewModel: SampleViewModel = .init()
@State private var isShowingDatePicker = false
var body: some View {
VStack {
HStack {
Spacer()
Button(action: {
isShowingDatePicker.toggle()
}) {
Text(viewModel.displayDate)
.font(.body)
.foregroundStyle(Color.blue)
}
.sheet(isPresented: $isShowingDatePicker) {
VStack {
DatePicker("Select a date", selection: $viewModel.selectedDate, displayedComponents: .date)
.datePickerStyle(.graphical)
.labelsHidden()
.padding()
Button("Done") {
isShowingDatePicker = false
}
.padding()
}
.presentationDetents([.medium])
}
Spacer()
}
.padding(.horizontal, 20)
.padding(.top, 25)
}
.onAppear {
updateDisplayDate()
}
.onChange(of: viewModel.selectedDate) { _ in
updateDisplayDate()
}
}
private func updateDisplayDate() {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm E, d MMM y"
viewModel.displayDate = formatter.string(from: viewModel.selectedDate)
}
}
Why is this better?
You don't rely on fragile SwiftUI internals (opacity hacks) anymore.
iOS 18 and forward compatibility is safer.
You fully control when and how the DatePicker appears.
You can even customize its style — graphical
, wheel
, or compact
.
You could try forcing a .datePickerStyle(.compact)
and no opacity tricks, but still wrap it in an invisible Button
to manage focus.
However, using .sheet
is much closer to the intended modern UX.