DatePicker SwiftUI Text/Font color styling...

This used to be possible to set the value for textColor key but I don't see how to do this within SwiftUI. Has anyone had any success with this or know how to set the appearance() global setting. Either works for me.


-Kevin.

Replies

Seems that .foregroundColor has no effect on a DatePicker.


But that works for a picker:

Picker(selection: $selectedColor, label: Text("color")) {
                   ForEach(0 ..< colors.count) {
                      Text(self.colors[$0])
                   }
                }.foregroundColor(.red)


In Swift, you do it with:

        datePicker.setValue(UIColor.red, forKeyPath: "textColor")
        datePicker.setValue(true, forKeyPath: "highlightsToday")}


I don't know how to do it in SwiftUI.

Looked here but did not yet figure out:

h ttps://gist.github.com/AliSoftware/ecb5dfeaa7884fc0ce96178dfdd326f8

Thanks Claude31. I live SwiftUI, but there are a bunch of places with complex UI's that it just isn't mature enough to completely convert over my existing project as a learning mechanism. I've had to make a few sacrifices to aesthetics. Hopefully, it will continue to be updated and over time will be a real IB replacement for most situations. Thanks for responding. I did use your answer in another place in code, so thank you and I hope this helps others.


-Kevin.

That UIDatePicker code looks suspiciously like it's accessing private state. Certainly `textColor` and `highlightsToday` aren't listed in the public API. Given that, it's unlikely you'll see those exposed by SwiftUI—private API will stay private.


Also, while `setValue(_:forKey:)` won't crash, it may simply stop working at some point in the future, silently failing. Apple may even mark the version that takes a plain String for the key argument as unavailable from Swift. Such facilities can be useful, but you take on the burden of manually confirming the behavior remains the same on every single point release, because it could go away (or gain/lose side-effects) at any time.

This works for macOS 11 and iOS 14 (Xcode 12 beta 3)...
  1. Take the Label out of the DatePicker - I've left it commented out here so its obvious to readers that the Label should be taken out of the DatePicker View.

  2. Place the DatePicker in an HStack (or other ViewBuilder)

  3. Add a Label for the DatePicker in the HStack

  4. Use the .colorMultiplier view modifier to change the color of the DatePicker date and time "button".

In this particular example I am also changing the colour of the date and time "button" depending on whether the binding value in the date picker is nil.

Code Block
        let now = Date()
        HStack {
            Text("Date")
            DatePicker(selection: Binding($observedObject.date, replacingNilWith: now)) {
//              Text("Date")
//                  .foregroundColor(Color(.label))
            }
            .colorMultiply(observedObject.date == nil ? Color(.placeholderText) : Color(.label))
        }


Also I'm using an extension to Binding in this example which is something I use throughout my core data projects.
Code Block
public extension Binding where Value: Equatable {
    init(_ source: Binding<Value?>, replacingNilWith nilProxy: Value) {
        self.init(
            get: { source.wrappedValue ?? nilProxy },
            set: { newValue in
                if newValue == nilProxy {
                    source.wrappedValue = nil
                }
                else {
                    source.wrappedValue = newValue
                }
        })
    }
}

As always full credit to Alan Quatermain for this extension to Binding.
Is there a cleaner native way to do this yet? I tried above example and it does not work for me.
Note that for iPad OS 14, using key paths will lead to a crash, because the changed control does not have that key path "highlightsToday" anymore:

datePicker.setValue(true, forKeyPath: "highlightsToday")

DatePicker("start date", selection: $start, displayedComponents: .date) .accentColor(.orange) .backgroundColor(.blue)