繁体   English   中英

SwiftUI 从视图中操作结构中的项目

[英]SwiftUI manipulate items from a struct from a view

我希望能够编辑用户添加的“费用”并将其放入新视图中。 添加新费用后,我在访问数据时遇到问题。 我可以删除项目并将其添加,但我想单击“费用”并查看和编辑其中的内容视图的图像

//内容视图

import SwiftUI

struct ExpenseItem: Identifiable, Codable {
    let id = UUID()
    let name: String
    let type: String
    let amount: Int
}

class Expenses: ObservableObject {
@Published var items = [ExpenseItem]() {
    didSet {
        let encoder = JSONEncoder()
        
        if let encoded = try?
            encoder.encode(items) {
            UserDefaults.standard.set(encoded, forKey: "Items")
        }
    }
}

init() {
    if let items = UserDefaults.standard.data(forKey: "Items") {
        let decoder = JSONDecoder()
        
        if let decoded = try?
            decoder.decode([ExpenseItem].self, from: items) {
            self.items = decoded
            return
        }
    }
}

// Computed property that calculates the total amount
var total: Int {
    self.items.reduce(0) { result, item -> Int in
        result + item.amount
    }
}
}

struct ContentView: View {
@ObservedObject var expenses = Expenses()
@State private var showingAddExpense = false

var body: some View {
    NavigationView {
        List {
            ForEach(expenses.items) { item in
                HStack {
                    VStack {
                        Text(item.name)
                            .font(.headline)
                        Text(item.type)
                    }
                    
                    Spacer()
                    Text("$\(item.amount)")
                }
            }
            .onDelete(perform: removeItems)
            
            // View that shows the total amount of the expenses
            HStack {
                Text("Total")
                Spacer()
                Text("\(expenses.total)")
            }
        }
        .navigationBarTitle("iExpense")
        .navigationBarItems(trailing: Button(action: {
            self.showingAddExpense = true
        }) {
            Image(systemName: "plus")
            }
        )
        .sheet(isPresented: $showingAddExpense) {
            AddView(expenses: self.expenses)
        }
    }
}

func removeItems(at offsets: IndexSet) {
    expenses.items.remove(atOffsets: offsets)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

//添加费用

import SwiftUI

struct AddView: View {
    @Environment(\.presentationMode) var presentationMode
    @ObservedObject var expenses: Expenses
    @State private var name = ""
    @State private var type = "Personal"
    @State private var amount = ""
    static let types = ["Business", "Personal"]

var body: some View {
    NavigationView {
        Form {
            TextField("Name", text: $name)
            
            Picker("Type", selection: $type) {
                ForEach(Self.types, id: \.self) {
                    Text($0)
                }
            }
            
            TextField("Amount", text: $amount)
                .keyboardType(.numberPad)
        }
        .navigationBarTitle("Add new expense")
        .navigationBarItems(trailing: Button("Save") {
            if let actualAmount = Int(self.amount) {
                let item = ExpenseItem(name: self.name, type: self.type, amount: actualAmount)
                self.expenses.items.append(item)
                self.presentationMode
                    .wrappedValue.dismiss()
            }
        })
    }
}
}

struct AddView_Previews: PreviewProvider {
    static var previews: some View {
        AddView(expenses: Expenses())
    }
}

在 AddView 中删除 @observedObject。

视图不能更改 ObservableObject。 ObservableObject 用于在值更改时得到通知。 当您将费用 class 传递给 AddView 时,您就是在给它一个参考。 因此,AddView 可以更改费用,从而更新 ContentView。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM