Center alignment of DatePicker in SwiftUI iOS 14

Viewed 2480

I have a DatePicker of GraphicalDatePickerStyle and I want to center it inside a rectangle. My code:

HStack {
        Spacer()
        DatePicker("", selection: $notificationTimeOnPicker, displayedComponents: .hourAndMinute).foregroundColor(Color("ChartColor")).labelsHidden()
                                .datePickerStyle(GraphicalDatePickerStyle())
        Spacer()
                            
        }

This is what I get and want:

enter image description here

How do I center my DatePicker? Looks like its frame is wide for some unknown reason. I tried changing its frame size to width: 95 or less to center it but after that I get ... instead of numbers when typing on some devices.

3 Answers

It seem works only with CompactDatePickerStyle

DatePicker("", selection: $notificationTimeOnPicker, displayedComponents: .hourAndMinute)
    .foregroundColor(Color("ChartColor"))           
    .datePickerStyle(CompactDatePickerStyle())
    .clipped()
    .labelsHidden()

The compact style was too small and the behaviour was strange for my requirements, so I reasonably hard coded the size considering accessibility as well:

struct ContentView: View {
    @Environment(\.sizeCategory) private var sizeCategory

    var body: some View {
            DatePicker("Select a time", selection: .constant(Date()), displayedComponents: .hourAndMinute)
                .datePickerStyle(GraphicalDatePickerStyle())
                .labelsHidden()
                .frame(maxWidth: CGFloat(sizeCategory.isAccessibilityCategory ? 235 : 200))
    }
}

The nice thing is SwiftUI dynamically squeezes / expands the picker to fit the width instead of clipping it.

Solution for UIKit

After several Google searches, I kept finding this post at the top of the results page, so I'm just going to answer here even though it doesn't exactly relate to the OP question, feel free to punish me ;).

Given this structure in Interface Builder:

enter image description here

In your View Controller, connect the Picker using an IBOutlet to access it programatically.

@IBOutlet weak var expirationDate: UIDatePicker!

And finally either in viewWillLayoutSubviews() or viewDidLayoutSubviews() put the following code:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    if let viewPicker = expirationDate.subviews.first?.subviews.first {
        // Force the date picker to be centered
        viewPicker.center.x = expirationDate.subviews.first!.center.x
    }
}

Hope you find it useful!

Related