10

Calendar view in SwiftUI with MultiDatePicker

 2 years ago
source link: https://sarunw.com/posts/swiftui-multidatepicker/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Calendar view in SwiftUI with MultiDatePicker


Table of Contents

In iOS 16, we have a dedicated calendar view, MultiDatePicker, that lets users select multiple dates.

It got the same looks as the graphical style (.graphical) DatePicker. The difference is users can select multiple dates as dictated by multiple highlights.

MultiDatePicker, a control for picking multiple dates.

MultiDatePicker, a control for picking multiple dates.

If you want to select a single date, you can use DatePicker.

In iOS 14, SwiftUI DatePicker has a graphical picker style that will present a date selector in a calendar form.

@State private var date = Date()

var body: some View {
DatePicker(
"Start Date",
selection: $date,
displayedComponents: [.date]
)
.datePickerStyle(.graphical)
}
DatePicker with a graphical picker style.

DatePicker with a graphical picker style.

You can easily support sarunw.com by checking out this sponsor.

swiftui_views_mastery.png

Sponsor sarunw.com and reach thousands of iOS developers.

How to use calendar view in SwiftUI

To use a MultiDatePicker, we only need to declare a Set<DateComponents> to hold a selected date.

struct MultiDatePickerExample: View {
@State private var dates: Set<DateComponents> = []

var body: some View {
MultiDatePicker("Dates Available", selection: $dates)
.fixedSize()
}
}

With this minimal setup, we got a working calendar view allowing users to select multiple dates from any point in time.

MultiDatePicker.

MultiDatePicker.

If you want to constrain users to select only a subset of available dates, you have three ways to do that (I hope we got more before the release).

Picking dates on or after a date

We can allow users to pick dates on or after a specified date by set PartialRangeFrom, e.g., startDate....

In this example, we allow date selection from June 20, 2022onward.

struct MultiDatePickerExample: View {
@Environment(\.calendar) var calendar
@Environment(\.timeZone) var timeZone

var bounds: PartialRangeFrom<Date> {
let start = calendar.date(
from: DateComponents(
timeZone: timeZone,
year: 2022,
month: 6,
day: 20)
)!

return start...
}

@State private var dates: Set<DateComponents> = []

var body: some View {
MultiDatePicker("Dates Available", selection: $dates, in: bounds)
.fixedSize()
}
}

Days before June 20, 2022, are inactive and gray out. It is also impossible to select the previous month and previous year.

Picking dates on or after a date.

Picking dates on or after a date.

Picking dates before a date

We can allow users to picking dates before a specified end date by set PartialRangeUpTo, e.g., ..<endDate.

In this example, we allow date selection before June 20, 2022 (not including June 20, 2022).

struct MultiDatePickerExample: View {
@Environment(\.calendar) var calendar
@Environment(\.timeZone) var timeZone

var bounds: PartialRangeUpTo<Date> {
let end = calendar.date(
from: DateComponents(
timeZone: timeZone,
year: 2022,
month: 6,
day: 20)
)!

return ..<end
}

@State private var dates: Set<DateComponents> = []

var body: some View {
MultiDatePicker("Dates Available", selection: $dates, in: bounds)
.fixedSize()
}
}

Days after June 20, 2022, are inactive and gray out. It is also impossible to select the next month and year.

PartialRangeUpTo shouldn't allow selection of June 20, 2022, but in the current beta, we can still select June 20, 2022.

I have filed a bug report and will update the post once I confirm the behavior.

Picking dates before a date.

Picking dates before a date.

Picking dates in a Range

You can set start and end available dates by specifying Range, e.g., startDate..<endDate.

In this example, we allow date selection from June 20, 2022 to from June 24, 2022.

struct MultiDatePickerExample: View {
@Environment(\.calendar) var calendar
@Environment(\.timeZone) var timeZone

var bounds: Range<Date> {
let start = calendar.date(
from: DateComponents(
timeZone: timeZone,
year: 2022,
month: 6,
day: 20)
)!
let end = calendar.date(
from: DateComponents(
timeZone: timeZone,
year: 2022,
month: 6,
day: 24)
)!

return start..<end
}

@State private var dates: Set<DateComponents> = []

var body: some View {
MultiDatePicker("Dates Available", selection: $dates, in: bounds)
.fixedSize()
}
}

Again, Range shouldn't allow selection of June 24, 2022, but in the current beta, we can still select June 24, 2022.

I have filed a bug report and will update the post once I can confirm the behavior.

Picking dates in a Range.

Picking dates in a Range.

You can easily support sarunw.com by checking out this sponsor.

swiftui_views_mastery.png

Sponsor sarunw.com and reach thousands of iOS developers.

Conclusion

I think a calendar view is a view that many people want. It still lacks many features in the current beta.

I hope we can get more features before the release. If you have any suggestions, you can submit feedback to Apple here (I already submit some).


You may also like

How to create multiline TextField in SwiftUI

In iOS 16, we can create a multiple text field with new initializers and a little help from the .lineLimit(_:) modifier.

SwiftUI iOS 16 WWDC22
How to change SwiftUI list background color

In iOS 16, we finally got a native way to change the background color of a list view in SwiftUI.

SwiftUI iOS 16

Read more article about SwiftUI, Calendar, WWDC22, iOS 16,

or see all available topic

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron

Buy me a coffee

Tweet

Share

Previous
How to create multiline TextField in SwiftUI

In iOS 16, we can create a multiple text field with new initializers and a little help from the .lineLimit(_:) modifier.

Next
How to get AppStore Connect Team ID and Developer Portal Team ID for Fastlane actions

If your Apple account belongs to multiple teams, this can cause Fastlane confusion. Learn how to fix it.

← Home


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK