I attempted my hand at my very own model of a calendar app. I can change the yr displayed within the overview utilizing arrow buttons. The present date is coloured purple.
Nevertheless, if I alter the yr after which swap again to the present date, the spotlight is gone. I can not work out tips on how to change this. Are you able to assist me? Right here I present you the code:
import SwiftUI
struct MonthOverviewView: View {
@State non-public var yr: Int = Calendar.present.part(.yr, from: Date()) // Aktuelles Jahr
@State non-public var scrollProxy: ScrollViewProxy? = nil
@State non-public var hasScrolledToToday = false // Verhindert mehrfaches Scrollen beim Laden der View
non-public let calendar = Calendar.present
non-public let daysOfWeek = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
non-public let currentDay = Calendar.present.part(.day, from: Date())
non-public let currentMonth = Calendar.present.part(.month, from: Date())
non-public let currentYear = Calendar.present.part(.yr, from: Date())
var physique: some View {
VStack {
// Jahresnavigation mit Heute Button
HStack {
Button(motion: {
yr -= 1
}) {
Picture(systemName: "chevron.left")
.font(.title2)
.padding()
}
// Vermeide Tausendertrennung in der Jahreszahl
Textual content("(String(yr))")
.font(.largeTitle)
.daring()
Button(motion: {
yr += 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)
}
yr = 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()), depend: 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()), depend: 7), spacing: 20) {
ForEach(getDaysInMonth(month: month, yr: yr), 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, yr: yr) ? .purple : .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(peak: 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 && yr == currentYear {
DispatchQueue.major.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, yr: Int) -> [Int] {
let dateComponents = DateComponents(yr: yr, month: month)
guard let firstOfMonth = calendar.date(from: dateComponents),
let vary = calendar.vary(of: .day, in: .month, for: firstOfMonth) else {
return []
}
let numberOfDays = vary.depend
let firstWeekday = calendar.part(.weekday, from: firstOfMonth) - 1 // Sonntag = 1, daher -1
var days = Array(repeating: 0, depend: 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, yr: Int) -> Bool {
return day == currentDay && month == currentMonth && yr == 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 strive, once I swap again from one other yr to the present yr, the func isToday doesn’t appear to be executed and the present date is not highlighted. This all the time appears to occur once I change the yr, as a result of so long as I solely scroll up or down within the present yr, the spotlight stays when the web page is loaded for the primary time.