Skip to content

Instantly share code, notes, and snippets.

@tjbarber
Last active December 15, 2020 15:50
Show Gist options
  • Save tjbarber/1a754e939a205aaaf3c36103f6e6c972 to your computer and use it in GitHub Desktop.
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
//
// 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