Skip to content

Instantly share code, notes, and snippets.

@maartene
Created November 9, 2019 16:04
Show Gist options
  • Save maartene/8a7a56d5225cb45b10b2ae66660a061f to your computer and use it in GitHub Desktop.
Save maartene/8a7a56d5225cb45b10b2ae66660a061f to your computer and use it in GitHub Desktop.
Day 47 Challenge - Habits app
//
// ContentView.swift
// Habits
//
// Created by Maarten Engels on 09/11/2019.
// Copyright © 2019 thedreamweb. All rights reserved.
//
import SwiftUI
struct Activity: Identifiable, Codable {
let id = UUID()
let title: String
let description: String
var count = 0
}
class Habits: ObservableObject {
@Published var activities = [Activity]() {
didSet {
let encoder = JSONEncoder()
if let data = try? encoder.encode(activities) {
UserDefaults.standard.set(data, forKey: "activities")
}
}
}
init() {
if let loadedActivities = UserDefaults.standard.data(forKey: "activities") {
let decoder = JSONDecoder()
if let decoded = try? decoder.decode([Activity].self, from: loadedActivities) {
self.activities = decoded
return
}
}
self.activities = []
}
func increaseCount(for activityID: UUID) {
guard let changedActivityIndex = activities.firstIndex(where: { $0.id == activityID }) else {
return
}
var changedActivity = activities[changedActivityIndex]
changedActivity.count += 1
activities[changedActivityIndex] = changedActivity
}
}
struct NewActivityView: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var habits: Habits
@State private var title = ""
@State private var description = ""
var body: some View {
NavigationView {
Form {
TextField("Title", text: $title)
TextField("Description", text: $description)
}
.navigationBarTitle("Add habit")
.navigationBarItems(leading:
Button("Back") {
self.presentationMode.wrappedValue.dismiss()
}, trailing:
Button("Save") {
self.saveNewHabit()
}
)
}
}
func saveNewHabit() {
let newHabit = Activity(title: title, description: description)
habits.activities.append(newHabit)
self.presentationMode.wrappedValue.dismiss()
}
}
struct ContentView: View {
@ObservedObject var habits = Habits()
@State private var showingAddActivitySheet = false
var body: some View {
NavigationView {
List {
ForEach(habits.activities) { activity in
HStack {
VStack(alignment: .leading) {
Text(activity.title).font(.headline)
Text(activity.description).font(.subheadline)
}
Spacer()
Button(action: {
self.habits.increaseCount(for: activity.id)
}) {
Text("Did it!")
.foregroundColor(Color.white)
.font(.headline)
.padding(8)
.background(Color.blue)
.clipShape(Capsule())
}
Text(String(activity.count)).font(.largeTitle)
.padding(8)
.clipShape(Circle())
.overlay(Circle().stroke(lineWidth: 2))
.shadow(radius: 2)
}
}.onDelete(perform: removeItems)
}
.navigationBarTitle("It's not a habit, it's cool, I feel alive")
.navigationBarItems(trailing:
Button(action: { self.showingAddActivitySheet.toggle() }) {
Image(systemName: "plus")
}
)
.sheet(isPresented: $showingAddActivitySheet) {
NewActivityView(habits: self.habits)
}
}
}
func removeItems(at offset: IndexSet) {
habits.activities.remove(atOffsets: offset)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment