I attempted my hand at my very own model of a calendar app. I can change the 12 months displayed within the overview utilizing arrow buttons. The present date is coloured crimson.
Nevertheless, if I alter the 12 months after which swap again to the present date, the spotlight is gone. I can not determine easy methods to change this. Are you able to assist me? Right here I present you the code:
import SwiftUI
struct MonthOverviewView: View {
@State personal var 12 months: Int = Calendar.present.part(.12 months, from: Date()) // Aktuelles Jahr
@State personal var scrollProxy: ScrollViewProxy? = nil
@State personal var hasScrolledToToday = false // Verhindert mehrfaches Scrollen beim Laden der View
personal let calendar = Calendar.present
personal let daysOfWeek = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
personal let currentDay = Calendar.present.part(.day, from: Date())
personal let currentMonth = Calendar.present.part(.month, from: Date())
personal let currentYear = Calendar.present.part(.12 months, from: Date())
var physique: some View {
VStack {
// Jahresnavigation mit Heute Button
HStack {
Button(motion: {
12 months -= 1
}) {
Picture(systemName: "chevron.left")
.font(.title2)
.padding()
}
// Vermeide Tausendertrennung in der Jahreszahl
Textual content("(String(12 months))")
.font(.largeTitle)
.daring()
Button(motion: {
12 months += 1
}) {
Picture(systemName: "chevron.proper")
.font(.title2)
.padding()
}
Spacer()
// Heute-Button für das Springen zum aktuellen Tag
TodayButton {
withAnimation {
scrollProxy?.scrollTo("day-(currentDay)-(currentMonth)", anchor: .middle)
}
12 months = currentYear
}
}
.padding(.vertical, 10)
// Scrollbare Monatsübersicht für das gesamte Jahr
ScrollViewReader { proxy in
ScrollView {
VStack(spacing: 40) {
ForEach(1...12, id: .self) { month in
VStack {
// Monatsüberschrift
Textual content("(calendar.monthSymbols[month - 1])")
.font(.title)
.daring()
// Wochentage
LazyVGrid(columns: Array(repeating: GridItem(.versatile()), rely: 7), spacing: 10) {
ForEach(daysOfWeek, id: .self) { day in
Textual content(day)
.font(.headline)
.body(maxWidth: .infinity)
}
}
// Tage des Monats anzeigen
LazyVGrid(columns: Array(repeating: GridItem(.versatile()), rely: 7), spacing: 20) {
ForEach(getDaysInMonth(month: month, 12 months: 12 months), id: .self) { day in
if day != 0 {
VStack(alignment: .main) {
// Spotlight für den aktuellen Tag durch rote Ziffer
Textual content("(day)")
.font(.physique) // Kleinere Ziffern
.daring()
.foregroundColor(isToday(day: day, month: month, 12 months: 12 months) ? .crimson : .black)
.padding(.backside, 10) // Abstand zum unteren Bereich
.padding(.main, 5)
// Platzhalter für spätere Termine, größerer Bereich
Rectangle()
.fill(Colour.clear) // Hintergrundfarbe entfernen
.body(top: 60) // Mehr Platz für Termine
}
.body(minHeight: 120) // Vergrößerter Bereich für jeden Tag
.border(Colour.grey.opacity(0.2), width: 1) // Dezenter Rahmen
.id("day-(day)-(month)") // Eindeutige ID für jeden Tag, damit genau dorthin gescrollt werden kann
} else {
Colour.clear // Platzhalter für leere Felder
}
}
}
.padding(.horizontal)
}
}
}
.onAppear {
scrollProxy = proxy // ScrollViewProxy speichern
// Nur einmalig beim ersten Laden der Ansicht zum aktuellen Tag scrollen
if !hasScrolledToToday && 12 months == currentYear {
DispatchQueue.important.async {
withAnimation {
proxy.scrollTo("day-(currentDay)-(currentMonth)", anchor: .middle)
hasScrolledToToday = true // Verhindert erneutes Scrollen beim erneuten Aufrufen der View
}
}
}
}
}
}
}
}
// Funktion zur Berechnung der Tage des Monats
func getDaysInMonth(month: Int, 12 months: Int) -> [Int] {
let dateComponents = DateComponents(12 months: 12 months, month: month)
guard let firstOfMonth = calendar.date(from: dateComponents),
let vary = calendar.vary(of: .day, in: .month, for: firstOfMonth) else {
return []
}
let numberOfDays = vary.rely
let firstWeekday = calendar.part(.weekday, from: firstOfMonth) - 1 // Sonntag = 1, daher -1
var days = Array(repeating: 0, rely: firstWeekday == 0 ? 6 : firstWeekday - 1) // Leerzeichen für die ersten Tage der Woche
days += Array(1...numberOfDays)
return days
}
// Überprüft, ob der aktuelle Tag angezeigt wird
func isToday(day: Int, month: Int, 12 months: Int) -> Bool {
return day == currentDay && month == currentMonth && 12 months == currentYear
}
}
struct TodayButton: View {
var motion: () -> Void
var physique: some View {
Button(motion: motion) {
Textual content("button_today")
// .font(.headline)
.padding(.horizontal)
.padding(.vertical, 8)
//.background(Colour.blue.opacity(0.1))
.cornerRadius(10)
}
.padding(.trailing, 10)
}
}
It doesn’t matter what I attempt, once I swap again from one other 12 months to the present 12 months, the func isToday doesn’t appear to be executed and the present date is now not highlighted. This all the time appears to occur once I change the 12 months, as a result of so long as I solely scroll up or down within the present 12 months, the spotlight stays when the web page is loaded for the primary time.