Last active
December 15, 2020 15:50
-
-
Save tjbarber/1a754e939a205aaaf3c36103f6e6c972 to your computer and use it in GitHub Desktop.
Simple Main/Detail Setup in SwiftUI where you can edit passed object in Detail view
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 | |
// ActivityTracker | |
// | |
// Created by TJ Barber on 12/10/20. | |
// | |
import SwiftUI | |
struct Activity: Identifiable, Codable, Hashable { | |
let id: UUID = UUID() | |
let name: String | |
let description: String | |
var timesCompleted: Int | |
func hash(into hasher: inout Hasher) { | |
hasher.combine(id) | |
} | |
} | |
class ActivityStore: ObservableObject { | |
private let keyPath = "activityStore" | |
@Published var items = [Activity]() { | |
didSet { | |
let encoder = JSONEncoder() | |
if let encoded = try? encoder.encode(items) { | |
UserDefaults.standard.setValue(encoded, forKeyPath: keyPath) | |
} | |
} | |
} | |
init() { | |
let decoder = JSONDecoder() | |
if let data = UserDefaults.standard.data(forKey: keyPath), | |
let decoded = try? decoder.decode([Activity].self, from: data) { | |
self.items = decoded | |
} | |
} | |
} | |
struct ContentView: View { | |
@ObservedObject var activityStore = ActivityStore() | |
@State private var showingAddActivity = false | |
var body: some View { | |
NavigationView { | |
List { | |
ForEach(Array(zip(activityStore.items.indices, activityStore.items)), id: \.1) { index, activity in | |
NavigationLink(destination: ActivityDetailView(activity: self.$activityStore.items[index])) { | |
HStack { | |
Text(activity.name) | |
Spacer() | |
Text("\(activity.timesCompleted)") | |
} | |
} | |
} | |
} | |
.listStyle(PlainListStyle()) | |
.navigationBarTitle("ActivityTracker") | |
.navigationBarItems(trailing: Button(action: { | |
showingAddActivity = true | |
}) { | |
Image(systemName: "plus") | |
}) | |
.sheet(isPresented: $showingAddActivity) { | |
AddActivityView(activityStore: activityStore) | |
} | |
} | |
} | |
} | |
struct AddActivityView: View { | |
@Environment(\.presentationMode) var presentationMode | |
@ObservedObject var activityStore: ActivityStore | |
@State private var name: String = "" | |
@State private var description: String = "" | |
var body: some View { | |
NavigationView { | |
Form { | |
TextField("Name", text: $name) | |
TextField("Description", text: $description) | |
} | |
.navigationBarTitle("Add Activity") | |
.navigationBarItems(trailing: Button("Save") { | |
let activity = Activity(name: self.name, description: self.description, timesCompleted: 0) | |
self.activityStore.items.append(activity) | |
self.presentationMode.wrappedValue.dismiss() | |
}) | |
} | |
} | |
} | |
struct ActivityDetailView: View { | |
@Binding var activity: Activity | |
var body: some View { | |
VStack { | |
Text(activity.name) | |
.font(.headline) | |
Text(activity.description) | |
Spacer() | |
Button("I did this!") { | |
activity.timesCompleted += 1 | |
print("\(activity.timesCompleted)") | |
} | |
.padding() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment