Day 47 of #100DaysOfSwiftUI

Start 100DaysOfSwiftUI from 2020.Mar.18th.

Day 47: Milestone: Project 7 - 9
done with 3 hours

New findings: followings are new findings

  • ForEach is still not so easy. especially handling binding variable is difficult
  • Type of TextField can handle is only text, it is troublesome.

ContentView

struct ContentView: View {
    @ObservedObject var activityList:ActivityList = ActivityList()
    @State private var showingNewActivitySheet = false
    
    var body: some View {
        NavigationView {
            List {
                ForEach(activityList.activities.indices, id:\.self) { index in
                    NavigationLink(destination: ActivityDetailView(activity: self.$activityList.activities[index]) ) {
                            VStack{
                                Text("Activity Name :  \(self.activityList.activities[index].name)")
                                Text("Activity Count:  \(self.activityList.activities[index].count)")
                            }
                    }
                }
                .onDelete(perform: removeActivity)
            }
            .navigationBarTitle("Activity Tracker")
            .navigationBarItems(leading: EditButton(), trailing: Button(action: {
                // currently nothing to do
                self.showingNewActivitySheet = true
            }, label: {
                Image(systemName: "plus")
            }))
        }
        .sheet(isPresented: $showingNewActivitySheet) {
            NewActivityView().environmentObject(self.activityList)
        }
    }
    
    func removeActivity(at offsets:IndexSet) {
        activityList.activities.remove(atOffsets: offsets)
    }
}

struct NewActivityView: View {
    @EnvironmentObject var activityList:ActivityList
    @Environment(\.presentationMode) var presentationMode
    @State var activityName = "New Activity"
    @State var activityNum = "0"
    
    var body: some View {
        NavigationView {
            Form {
                TextField("Activity Name", text: $activityName)
                TextField("Activity Count", text: $activityNum)
            }
        .navigationBarTitle("Add new activity")
            .navigationBarItems(trailing: Button("Add New") {
                if let actNum = Int(self.activityNum) {
                    let activity = Activity(name: self.activityName,
                                            count: actNum)
                    self.activityList.activities.append(activity)
                }
                self.presentationMode.wrappedValue.dismiss()

            })
        }
    }
}

Activity.swift

struct Activity: Identifiable, Codable {
    var id:UUID = UUID()
    public var name: String
    public var count:Int
}

ActivityList.swift

class ActivityList: ObservableObject {
    @Published var activities:[Activity] {
        didSet {
            let encoder = JSONEncoder()
            if let encoded = try? encoder.encode(activities) {
                UserDefaults.standard.set(encoded, forKey: "Activities")
            }
        }
    }
    init() {
        if let activities = UserDefaults.standard.data(forKey: "Activities") {
            let decoder = JSONDecoder()
            if let decoded = try? decoder.decode([Activity].self, from: activities) {
                self.activities = decoded
                return
            }
        }

        self.activities = []
    }
    
}

ActivityDetailView.swift

struct ActivityDetailView: View {
    @Binding var activity:Activity
    @State var tmpStr:String = ""
    
    var body: some View {
        VStack {
            Text("Activity Name  : \(activity.name)")
            Text("Activity Count : \(activity.count)")
            Button("Increment Count") {
                self.activity.count += 1
            }
        }
    }
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です