ios-tracker/HabitTracker/Views/AddHabitView.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

101 lines
3.6 KiB
Swift

import SwiftUI
import SwiftData
struct AddHabitView: View {
@Environment(\.modelContext) private var context
@Environment(\.dismiss) private var dismiss
@State private var name = ""
@State private var symbolName = "star.fill"
@State private var colorHex = "#34C759"
@State private var reminderTime: Date?
private let symbols = [
"star.fill", "drop.fill", "flame.fill", "book.fill", "dumbbell.fill",
"leaf.fill", "heart.fill", "moon.fill", "cup.and.saucer.fill", "figure.run"
]
private let colors = ["#34C759", "#007AFF", "#FF9500", "#FF2D55", "#AF52DE", "#5AC8FA"]
private let columns = [GridItem(.adaptive(minimum: 44), spacing: 12)]
var body: some View {
NavigationStack {
Form {
Section("Name") {
TextField("z. B. Wasser trinken", text: $name)
}
Section("Symbol") {
LazyVGrid(columns: columns, spacing: 12) {
ForEach(symbols, id: \.self) { symbol in
Image(systemName: symbol)
.font(.title2)
.frame(width: 44, height: 44)
.background(symbol == symbolName ? Color(hex: colorHex).opacity(0.2) : Color.clear)
.foregroundStyle(symbol == symbolName ? Color(hex: colorHex) : Color.secondary)
.clipShape(RoundedRectangle(cornerRadius: 10))
.onTapGesture { symbolName = symbol }
}
}
.padding(.vertical, 4)
}
Section("Farbe") {
HStack(spacing: 12) {
ForEach(colors, id: \.self) { hex in
Circle()
.fill(Color(hex: hex))
.frame(width: 32, height: 32)
.overlay {
if hex == colorHex {
Image(systemName: "checkmark")
.font(.caption.bold())
.foregroundStyle(.white)
}
}
.onTapGesture { colorHex = hex }
}
}
.padding(.vertical, 4)
}
Section("Erinnerung") {
ReminderEditor(reminderTime: $reminderTime)
}
}
.navigationTitle("Neue Gewohnheit")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Abbrechen") { dismiss() }
}
ToolbarItem(placement: .confirmationAction) {
Button("Sichern") { save() }
.disabled(trimmedName.isEmpty)
}
}
}
}
private var trimmedName: String {
name.trimmingCharacters(in: .whitespacesAndNewlines)
}
private func save() {
let habit = Habit(
name: trimmedName,
symbolName: symbolName,
colorHex: colorHex,
reminderTime: reminderTime
)
context.insert(habit)
NotificationManager.reschedule(for: habit)
WidgetSync.refresh(context)
dismiss()
}
}
#Preview {
AddHabitView()
.modelContainer(for: [Habit.self, HabitEntry.self], inMemory: true)
}