The times of the week are the 7 days following any date, like immediately. So should you construct a listing with the subsequent 7 dates from immediately, you get all of the day names in every week, within the order decided by no matter day immediately is.
To have the listing in a particular order, with Monday or Sunday being the primary, simply discover the subsequent Monday or Sunday from immediately and get the subsequent 7 dates following that date.
You need to use the date formatter to format the day names nonetheless you want.
For “selecting” days, you want a state that holds the day title and an related bool worth:
@State personal var daySelections: [(day: String, isSelected: Bool)] = []
You also needs to have a view representing a particular day and its standing, which might settle for the day and a binding to the bool worth as parameters. It will let you type the view representing the day as wanted and toggle the choice from that youngster view.
This is the working code:
import SwiftUI
// A horizontal container that picks days
struct DaysPicker: View {
//A state to carry the times and their choice standing
@State personal var daySelections: [(day: String, isSelected: Bool)] = []
// Computed property to get chosen days
personal var selectedDays: [String] {
daySelections.filter { $0.isSelected }.map { $0.day }
}
//Physique
var physique: some View {
VStack {
HStack(spacing: 0) {
ForEach(daySelections.indices, id: .self) { index in
let day = daySelections[index].day
DaysCircle(day: day, isSelected: $daySelections[index].isSelected) //move a binding to the day's isSelected worth
}
}
.padding()
VStack {
Textual content("Chosen days: (selectedDays.rely)")
.foregroundStyle(.secondary)
.padding()
ForEach(selectedDays, id: .self) { day in
Textual content(day)
.textCase(.uppercase)
.foregroundStyle(.inexperienced)
}
}
Spacer()
}
.onAppear {
daySelections = getDayNames()
}
}
//Operate to construct listing of day names with related bool worth for choice
personal func getDayNames() -> [(day: String, isSelected: Bool)] {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale.present
dateFormatter.dateFormat = "E" // "E" provides a brief model like "Mon", "Tue"
let calendar = Calendar.present
let immediately = calendar.startOfDay(for: Date())
let weekday = calendar.part(.weekday, from: immediately)
let daysUntilMonday = (9 - weekday) % 7
let startOfWeek = calendar.date(byAdding: .day, worth: daysUntilMonday, to: immediately)!
var daysOfWeek: [(String, Bool)] = []
for i in 0..<7 {
if let day = calendar.date(byAdding: .day, worth: i, to: startOfWeek) {
let dayName = dateFormatter.string(from: day)
daysOfWeek.append((dayName, false)) // Initialize every day with isSelected as false
}
}
return daysOfWeek
}
}
struct DaysCircle: View {
//Parameters
var day: String
@Binding var isSelected: Bool
//Physique
var physique: some View {
Button {
withAnimation {
isSelected.toggle()
}
} label: {
Textual content("(day)")
.textCase(.uppercase)
.font(.caption)
.fixedSize()
.foregroundStyle(.white)
.padding()
.background(isSelected ? .inexperienced : .cyan, in: Circle())
}
}
}
#Preview {
DaysPicker()
}