ios-tracker/HabitTracker/Views/HabitListView.swift
rene 22b8f5d806 Initiales HabitTracker-Projekt: SwiftUI + SwiftData Gewohnheiten-Tracker
Natives iOS-App-Gerüst (Xcode 26, synchronisierte Ordner, iOS 18+).

Features:
- Gewohnheiten anlegen (Name, SF-Symbol, Farbe), heute abhaken, Streaks, Löschen
- Detailansicht mit Monatskalender (Tage nachtragbar) und Statistiken
- Tägliche Erinnerungen via lokale Notifications
- Home-Screen-Widget (klein/mittel) mit App-Group-Datenaustausch
2026-05-29 21:12:45 +02:00

69 lines
2.1 KiB
Swift

import SwiftUI
import SwiftData
struct HabitListView: View {
@Environment(\.modelContext) private var context
@Environment(\.scenePhase) private var scenePhase
@Query(sort: \Habit.createdAt) private var habits: [Habit]
@State private var showingAdd = false
var body: some View {
NavigationStack {
Group {
if habits.isEmpty {
ContentUnavailableView(
"Keine Gewohnheiten",
systemImage: "checklist",
description: Text("Tippe auf +, um deine erste Gewohnheit anzulegen.")
)
} else {
List {
ForEach(habits) { habit in
NavigationLink {
HabitDetailView(habit: habit)
} label: {
HabitRowView(habit: habit)
}
}
.onDelete(perform: delete)
}
}
}
.navigationTitle("Heute")
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
showingAdd = true
} label: {
Label("Hinzufügen", systemImage: "plus")
}
}
}
.sheet(isPresented: $showingAdd) {
AddHabitView()
}
}
.task {
WidgetSync.refresh(context)
}
.onChange(of: scenePhase) { _, phase in
if phase == .active {
WidgetSync.refresh(context)
}
}
}
private func delete(at offsets: IndexSet) {
for index in offsets {
let habit = habits[index]
NotificationManager.cancel(for: habit)
context.delete(habit)
}
WidgetSync.refresh(context)
}
}
#Preview {
HabitListView()
.modelContainer(for: [Habit.self, HabitEntry.self], inMemory: true)
}