How to make a button (or any other element) show SwiftUI’s DatePicker popup on tap?

I’m having this problem too. I couldn’t sleep for a few days thinking about the solution. I have googled hundred times and finally, I found a way to achieve this. It’s 1:50 AM in my timezone, I can sleep happily now. Credit goes to chase’s answer here

Demo here: https://media.giphy.com/media/2ILs7PZbdriaTsxU0s/giphy.gif

The code that does the magic

struct ContentView: View {
    @State var date = Date()
    
    var body: some View {
        ZStack {
            DatePicker("label", selection: $date, displayedComponents: [.date])
                .datePickerStyle(CompactDatePickerStyle())
                .labelsHidden()
            Image(systemName: "calendar")
                .resizable()
                .frame(width: 32, height: 32, alignment: .center)
                .userInteractionDisabled()
        }
    }
}

struct NoHitTesting: ViewModifier {
    func body(content: Content) -> some View {
        SwiftUIWrapper { content }.allowsHitTesting(false)
    }
}

extension View {
    func userInteractionDisabled() -> some View {
        self.modifier(NoHitTesting())
    }
}

struct SwiftUIWrapper<T: View>: UIViewControllerRepresentable {
    let content: () -> T
    func makeUIViewController(context: Context) -> UIHostingController<T> {
        UIHostingController(rootView: content())
    }
    func updateUIViewController(_ uiViewController: UIHostingController<T>, context: Context) {}
}

Leave a Comment