Label for DatePicker

I would like to provide a label for a DatePicker in my app. The built-in label is on the left and totally vertical (one letter per line). I tried using a Text(“Label”) above it, but it doesn’t look very good.

Is there a way to make the built-in label show up horizontally above the DatePicker, or do you have any other suggestions?


Can you show us the code you have and/or a screen capture of your UI layout so that we have a rough idea of what you are trying to do.

If you paste your code, put three back-ticks ``` on the line above and below the code so that it is formatted nicely.

I want to have a label that says “Expiration Date:” just above the DatePicker. If I specify a label in DatePicker, it displays vertically left of the DatePicker. Inserting Text(“Expiration Date:” between the Name field and the DatePicker doesn’t look like a label.

What version of Xcode are you using? If you are using Xcode 12+ then why not use the standard date picker which is a single row. ie:

DatePicker("Expiration Date", selection: $myDate, displayedComponents: .date)

It looks like this on the screen.

When you tap on the date it pops up a Calendar which looks like this and allows you to select a date

My app deals with subscriptions, which usually expire on a yearly basis. A new subscription would likely have an expiration date one or more years from the current date. The DatePicker type I’m using makes it easy to advance in increments of years. The new style requires twelve clicks to advance each year.

Hmm, I’m looking at your screen shot and I wonder if that arrow next to the year will advance a year. I can’t try it now because I’m not at my computer. If that’s the case, it’s much better, but still a couple of clicks more. Might be worth it, though.

Thanks for the suggestion.

In your code you can default the starting date as 12 months or two years from the current date which will allow the user to make any fine adjustments required.

Yeah, I’m still new at this. I think I found some info on how to add a year to a date. It’s almost dinner time, so I’ll have to look at that tomorrow.

Meanwhile, that new format looks much nicer and is more compact than the one I was using. One thing I noticed, though, is, even though the date starts out as, for example, Feb 4, 2021, if I add a year, it’s now displayed as 2/4/22. Don’t know if that’s a bug or a feature.

I thought you might be interested in that option and that’s why I posted that line of code.

The other option is that you can define a closed range of dates you can work in. Like this:

DatePicker("Expiration Date", selection: $myDate, in: Date()..., displayedComponents: .date)

The in: parameter is the closed range. Date()... means anything from todays date forward which prevents the user from selecting a date in history.

The parameter displayedComponents: .date means confine the picker to date only.

Another interesting approach when dealing with date ranges is the scenario where you want to restrict birthdate selection as in the following.

 DatePicker("Birthday", selection: $birthday,
                                   in: Date().oneHundredTenYearsAgo...Date().eighteenYearsAgo,
                                   displayedComponents: .date)

What that does is effectively say, “You can’t be older that 110 years and you can’t be younger than 18”.

The extension on Date has two computed values used in the above.

extension Date {
    var eighteenYearsAgo: Date { .year, value: -18, to:  Date())!
    var oneHundredTenYearsAgo: Date { .year, value: -110, to:  Date())!

That’s beautiful! I set the default date to one year from today. Thanks, now I know how to do that.

Is it safe to force unwrap it? What condition would make it fail?

I don’t know which one you need to force unwrap. Can you share some code so that I can see what you are referring to.

I was referring to the two computed properties in the Date extension that you provided.

Oh right.

The function .date(byAdding: .year, value: -18, to: Date()) returns an optional and since we know that Date() always returns the current date, it is safe to unwrap.