簡體   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