В чем причина того, что функция isToday выполняется неправильно?IOS

Программируем под IOS
Ответить
Anonymous
 В чем причина того, что функция isToday выполняется неправильно?

Сообщение Anonymous »

Я попробовал свою версию приложения-календаря. Я могу изменить год, отображаемый в обзоре, с помощью кнопок со стрелками. Текущая дата окрашена в красный цвет.
Однако, если я изменю год, а затем вернусь к текущей дате, выделение исчезнет. Я не могу понять, как это изменить. Вы можете помочь мне? Здесь я покажу вам код:

Код: Выделить всё

import SwiftUI

struct MonthOverviewView: View {
@State private var year: Int = Calendar.current.component(.year, from: Date()) // Aktuelles Jahr
@State private var scrollProxy: ScrollViewProxy? = nil
@State private var hasScrolledToToday = false // Verhindert mehrfaches Scrollen beim Laden der View
private let calendar = Calendar.current
private let daysOfWeek = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
private let currentDay = Calendar.current.component(.day, from: Date())
private let currentMonth = Calendar.current.component(.month, from: Date())
private let currentYear = Calendar.current.component(.year, from: Date())

var body: some View {
VStack {
// Jahresnavigation mit Heute Button
HStack {
Button(action: {
year -= 1
}) {
Image(systemName: "chevron.left")
.font(.title2)
.padding()
}

// Vermeide Tausendertrennung in der Jahreszahl
Text("\(String(year))")
.font(.largeTitle)
.bold()

Button(action: {
year += 1
}) {
Image(systemName: "chevron.right")
.font(.title2)
.padding()
}

Spacer()

// Heute-Button für das Springen zum aktuellen Tag
TodayButton {
withAnimation {
scrollProxy?.scrollTo("day-\(currentDay)-\(currentMonth)", anchor: .center)
}
year = 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
Text("\(calendar.monthSymbols[month - 1])")
.font(.title)
.bold()

// Wochentage
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 7), spacing: 10) {
ForEach(daysOfWeek, id: \.self) { day in
Text(day)
.font(.headline)
.frame(maxWidth: .infinity)
}
}

// Tage des Monats anzeigen
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 7), spacing: 20) {
ForEach(getDaysInMonth(month: month, year: year), id: \.self) { day in
if day != 0 {
VStack(alignment: .leading) {
// Highlight für den aktuellen Tag durch rote Ziffer
Text("\(day)")
.font(.body) // Kleinere Ziffern
.bold()
.foregroundColor(isToday(day: day, month: month, year: year) ? .red :  .black)
.padding(.bottom, 10) // Abstand zum unteren Bereich
.padding(.leading, 5)

// Platzhalter für spätere Termine, größerer Bereich
Rectangle()
.fill(Color.clear) // Hintergrundfarbe entfernen
.frame(height: 60) // Mehr Platz für Termine
}
.frame(minHeight: 120) // Vergrößerter Bereich für jeden Tag
.border(Color.gray.opacity(0.2), width: 1) // Dezenter Rahmen
.id("day-\(day)-\(month)") // Eindeutige ID für jeden Tag, damit genau dorthin gescrollt werden kann
} else {
Color.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 && year == currentYear {
DispatchQueue.main.async {
withAnimation {
proxy.scrollTo("day-\(currentDay)-\(currentMonth)", anchor: .center)
hasScrolledToToday = true // Verhindert erneutes Scrollen beim erneuten Aufrufen der View
}
}
}
}
}
}
}
}

// Funktion zur Berechnung der Tage des Monats
func getDaysInMonth(month: Int, year: Int) -> [Int] {
let dateComponents = DateComponents(year: year, month: month)
guard let firstOfMonth = calendar.date(from: dateComponents),
let range = calendar.range(of: .day, in: .month, for: firstOfMonth) else {
return []
}

let numberOfDays = range.count
let firstWeekday = calendar.component(.weekday, from: firstOfMonth) - 1 // Sonntag = 1, daher -1

var days = Array(repeating: 0, count: 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, year: Int) -> Bool {
return day == currentDay && month == currentMonth && year == currentYear
}
}

struct TodayButton: View {
var action: () -> Void

var body: some View {
Button(action: action) {
Text("button_today")
// .font(.headline)
.padding(.horizontal)
.padding(.vertical, 8)
//.background(Color.blue.opacity(0.1))
.cornerRadius(10)
}
.padding(.trailing, 10)
}
}
Что бы я ни пытался, когда я переключаюсь обратно с другого года на текущий год, функция isToday, похоже, не выполняется, и текущая дата больше не выделяется. Кажется, это всегда происходит, когда я меняю год, потому что, пока я прокручиваю только вверх или вниз в текущем году, выделение остается при первой загрузке страницы.


Подробнее здесь: https://stackoverflow.com/questions/790 ... -correctly
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»