-
-
Save mjarraya/ed2e6a0a4b9a961597f04a019701dbfc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ContentView.swift | |
// HabitTracker | |
// | |
// Created by Montasar on 05/05/2020. | |
// Copyright © 2020 Montasar. All rights reserved. | |
// | |
import SwiftUI | |
struct Activity: Identifiable, Codable { | |
let id = UUID() | |
let name: String | |
let description: String | |
var count: Int | |
// init(name: String, description: String, count: Int) { | |
// self.id = UUID() | |
// self.name = name | |
// self.description = description | |
// self.count = count | |
// } | |
} | |
class Activities: ObservableObject { | |
@Published var items = [Activity]() { | |
didSet { | |
let encoder = JSONEncoder() | |
if let encoded = try? encoder.encode(items) { | |
UserDefaults.standard.set(encoded, forKey: "activities") | |
} | |
} | |
} | |
init() { | |
let decoder = JSONDecoder() | |
if let activities = UserDefaults.standard.data(forKey: "activities") { | |
if let decoded = try? decoder.decode([Activity].self, from: activities) { | |
self.items = decoded | |
return | |
} | |
} | |
self.items = [] | |
} | |
} | |
struct AddActivity: View { | |
@Environment (\.presentationMode) var presentationMode | |
@ObservedObject var activities: Activities | |
@State private var name = "" | |
@State private var description = "" | |
func createActivity() { | |
let activity = Activity(name: name, description: description, count: 1) | |
activities.items.append(activity) | |
} | |
var body: some View { | |
NavigationView { | |
VStack { | |
TextField("Activity name", text: $name) .multilineTextAlignment(TextAlignment.center).padding(10) | |
TextField("Description", text: $description) .multilineTextAlignment(TextAlignment.center).padding(10) | |
Button(action: { | |
self.createActivity() | |
self.presentationMode.wrappedValue.dismiss() | |
}) { | |
Text("Create").padding( .vertical, 5).padding(.horizontal, 15).foregroundColor(.white) | |
.background(Color.blue).cornerRadius(20) | |
} | |
} | |
.navigationBarItems(trailing: Button("Cancel") { | |
self.presentationMode.wrappedValue.dismiss() | |
}) | |
} | |
} | |
} | |
struct ActivityDetail: View { | |
@State var activity: Activity | |
@ObservedObject var activities: Activities | |
func incrementCount() { | |
// here is the ugly part where I would have preferred to use an ObservedObject and mutate it directly | |
if let index = activities.items.firstIndex(where: { $0.id == activity.id }) { | |
var newActivity = activities.items[index] | |
newActivity.count += 1 | |
activities.items[index] = newActivity | |
activity = newActivity | |
} | |
} | |
var body: some View { | |
VStack { | |
Text(activity.name) | |
Text(activity.description) | |
Text("Completed \(activity.count) times") | |
Button(action: { | |
self.incrementCount() | |
}) { | |
Text("Increment").padding( .vertical, 5).padding(.horizontal, 15).foregroundColor(.white) | |
.background(Color.blue).cornerRadius(20) | |
} | |
} | |
} | |
} | |
struct ContentView: View { | |
@State private var showingAddActivity = false | |
@ObservedObject var activities = Activities() | |
func removeActivity(at offsets: IndexSet) { | |
activities.items.remove(atOffsets: offsets) | |
} | |
var body: some View { | |
NavigationView { | |
List { | |
ForEach(activities.items) { item in | |
NavigationLink(destination: ActivityDetail(activity: item, activities: self.activities)) { | |
Text("\(item.name) (\(item.count))") | |
} | |
}.onDelete(perform: removeActivity) | |
} | |
.navigationBarTitle("HabitTracker") | |
.navigationBarItems(trailing: Button(action: { | |
self.showingAddActivity.toggle() | |
}) { | |
HStack { | |
Image(systemName: "plus") | |
Text("Add an activity") | |
} | |
}) | |
.sheet(isPresented: $showingAddActivity) { | |
AddActivity(activities: self.activities) | |
} | |
} | |
} | |
} | |
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