Greetings, traveler!
We continue our series about SwiftUI Week Calendar View. This is the fourth part, where we will create the WeekView
.
If you just want to check out the complete source code, here it is.
Let’s start with the WeekView
. This view will represent seven weekdays. According to our concept, we will generate three tabs with a Week
representation. This approach will allow us to create an infinite Week Calendar.
Properties
First, let’s create a WeekView
. It will have a property to hold a Week
model instance. Another property will represent a selected date value. We must mark this property as Binding
to provide data outside and receive it from there.
public struct WeekView: View {
var week: Week
@Binding var selectedDay: Date
public var body: some View {
}
}
Date management
We will use the ForEach
View to loop all the Week
model’s dates and create a view for them. But before we do this, let’s add some extensions to the Date
. You can put them to the same extension we created before or make another one. We should do this to mark weekdays with a specific style.
First, we need to create a function that returns a Bool
value to determine whether the chosen date is the same day as our binding selectedDay
property.
extension Date {
func isSameDay(with date: Date) -> Bool {
Calendar.current.compare(self, to: date, toGranularity: .day) == .orderedSame
}
}
Now, we can create a computed property that will help us determine whether the chosen date is today.
extension Date {
var isToday: Bool {
isSameDay(with: .now)
}
func isSameDay(with date: Date) -> Bool {
Calendar.current.compare(self, to: date, toGranularity: .day) == .orderedSame
}
}
Weekdays
We can create a VStack
with the day of the month and a weekday name to display weekdays. We can also use our Date
extensions to handle accent color. Then, we can wrap it inside the ForEach
View, and we are good to go.
public struct WeekView: View {
var week: Week
@Binding var selectedDay: Date
public var body: some View {
HStack {
ForEach(week.dates, id: \.self) { date in
VStack {
Text(date.formatted(.dateTime.weekday()).capitalized)
.foregroundColor(.primary)
.frame(maxWidth: .infinity)
.font(font)
.fontWeight(.semibold)
Circle()
.foregroundColor(date.isSameDay(with: selectedDay) && !date.isToday ? .blue.opacity(0.5) : .clear)
.frame(height: circleHeight)
.overlay {
ZStack {
if date.isToday {
Circle()
.foregroundColor(.blue)
.frame(height: 32)
}
Text(date.formatted(.dateTime.day(.twoDigits)))
.frame(maxWidth: .infinity)
.font(font)
.foregroundColor(date.isToday || date.isSameDay(with: selectedDay) ? .blue : .primary)
}
}
}.onTapGesture {
selectedDay = date
}
.frame(maxWidth: .infinity)
}
}
.padding()
}
}
Conclusion
We are done with the WeekView
and ready to create our WeekCalendarView
.
If you enjoyed this article, please feel free to follow me on my social media: