Search code examples
macosswiftuidatepicker

SwiftUI/macOS: DatePicker without background field


How do I get rid of the shaded background of the DatePicker field in macOS(!)?
.textFieldStyle or .background have no effect.

I tried this: Changing TextEditor background color in SwiftUI for macOS but seems to work only for TextField, TextEditor. Is there another NSView property that could be set?

        DatePicker("Start",
                   selection: $newDate,
                   displayedComponents: [.date])
            .datePickerStyle(.field)
//          .textFieldStyle(.plain)
//          .background(.clear)

enter image description here


Solution

  • Here is a simplified demo of representable wrapper approach

    Tested with Xcode 13.2 / macOS 12.1

    enter image description here

    struct DemoView: View {
        @State private var newDate: Date = Date()
    
        var body: some View {
            VStack {
                Text("Selected: \(newDate)")
                MyDatePicker(selection: $newDate)
            }
        }
    }
    
    struct MyDatePicker: NSViewRepresentable {
        @Binding var selection: Date
    
        func makeNSView(context: Context) -> NSDatePicker {
            let picker = NSDatePicker()
            picker.isBordered = false
            picker.datePickerStyle = .textField
            picker.action = #selector(Coordinator.onValueChange(_:))
            picker.target = context.coordinator
            return picker
        }
    
        func updateNSView(_ picker: NSDatePicker, context: Context) {
            picker.dateValue = selection
        }
    
        func makeCoordinator() -> Coordinator {
            Coordinator(owner: self)
        }
    
        class Coordinator: NSObject {
            private let owner: MyDatePicker
            init(owner: MyDatePicker) {
                self.owner = owner
            }
    
            @objc func onValueChange(_ sender: Any?) {
                if let picker = sender as? NSDatePicker {
                    owner.selection = picker.dateValue
                }
            }
        }
    }