0

在使用 AddView 选择它后,我想向用户展示一个选择器选项。DetailView 启动的 EditView 向我显示 Textfield 已满,但 Picker 仍然为空,尽管我之前选择了一个项目。

我创建了两个与 2 个数组相关的模型(都是可识别的、可编码的、可计算的、可散列的):

  • 杂货(模型)--->杂货(数组)
  • Food(model) ----> shoppingChart (array)

我的目标是通过指定名称并从 Picker 中选择存储在 shoppingChart 中的食物来添加新的杂货店。我使用 AddView 来存储杂货店,并使用 DetailView 中的 EditButton 来编辑存储的数据。我使用切换“如果”来激活选择器。

这是代码:

class Food: Hashable, Codable, Equatable, Identifiable {

var id : UUID = UUID()
var name : String

init(name: String) {
    self.name = name
}

static func == (lhs: Food, rhs: Food) -> Bool {
    return lhs.name == rhs.name
}

func hash(into hasher: inout Hasher) {
hasher.combine(name)
}

enum CodinKeys: String, CodingKey {
    case name
}

required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodinKeys.self)
    self.name = try container.decode(String.self, forKey: .name)
}

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodinKeys.self)
    try container.encode(name, forKey: .name)
}
}

class Grocery: Hashable, Codable, Equatable, Identifiable {

var id : UUID = UUID()
var name : String
var monday : String
var tuesday : String
var wednesday : String

init(name: String, monday: String, tuesday: String, wednesday: String) {
self.name = name
self.monday = monday
self.tuesday = tuesday
self.wednesday = wednesday
}

static func == (lhs: Grocery, rhs: Grocery) -> Bool {
    return lhs.name == rhs.name
}

func hash(into hasher: inout Hasher) {
hasher.combine(name)
hasher.combine(monday)
hasher.combine(tuesday)
hasher.combine(wednesday)
}

enum CodinKeys: String, CodingKey {
    case name
    case monday
    case tuesday
    case wednesday
}

required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodinKeys.self)
    self.name = try container.decode(String.self, forKey: .name)
    self.monday = try container.decode(String.self, forKey: .monday)
    self.tuesday = try container.decode(String.self, forKey: .tuesday)
    self.wednesday = try container.decode(String.self, forKey: .wednesday)
}

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodinKeys.self)
    try container.encode(name, forKey: .name)
    try container.encode(monday, forKey: .monday)
    try container.encode(tuesday, forKey: .tuesday)
    try container.encode(wednesday, forKey: .wednesday)
}
}

import SwiftUI
import Combine

class FoodManager: ObservableObject {

@Published var shoppingChart: [Food] = []

init() {

        let milk = Food(name: "Milk")
        let coffee = Food(name: "Coffee")

        shoppingChart.append(milk)
        shoppingChart.append(coffee)        
}


func newFood(name: String) {
    let food = Food(name: name)
    shoppingChart.insert(food, at: 0)
}

func editFood(id: UUID, name: String) {

    if let food = (shoppingChart.filter { $0.id.uuidString == id.uuidString }).first {
        food.name = name
    }
}
}

class GroceryManager: ObservableObject {

@Published var groceries: [Grocery] = []

init() {

        let grocery_1 = Grocery(name: "Walmart", monday: "", tuesday: "", wednesday: "")
        let grocery_2 = Grocery(name: "Whole Foods", monday: "", tuesday: "", wednesday: "")

        groceries.append(grocery_1)
        groceries.append(grocery_2)
}


func newGrocery(name: String, monday: String, tuesday: String, wednesday: String) {
    let grocery = Grocery(name: name, monday: monday, tuesday: tuesday, wednesday: wednesday)
    groceries.insert(grocery, at: 0)
}

func editGrocery(id: UUID, name: String, monday: String, tuesday: String, wednesday: String)     {

    if let grocery = (groceries.filter { $0.id.uuidString == id.uuidString }).first {
        grocery.name = name
        grocery.monday = monday
        grocery.tuesday = tuesday
        grocery.wednesday = wednesday
    }
}
}

struct ContentView: View {

@ObservedObject var food_dm : FoodManager
@ObservedObject var grocery_dm : GroceryManager

@State var isAddGroceryViewOpened = false
@State var isEditOpened = false
@State var fieldtext : String = ""
var grocery : Grocery?

var body: some View {
    NavigationView {
        VStack {
            List {
                ForEach(self.grocery_dm.groceries, id:\.self) { grocery in
                    NavigationLink(destination: DetailView(grocery_dm: self.grocery_dm, food_dm: self.food_dm, grocery: grocery))
                    {
                        HStack {
                            Text(grocery.name)

                        }
                    }
                }
            }
            buttonAdd
        }

    }
}

var buttonAdd: some View {
    Button(action: {
        self.isAddGroceryViewOpened.toggle()
    }) {
        Text("Add")
    }
    .sheet(isPresented: $isAddGroceryViewOpened) {
        AddGroceryView(food_dm: self.food_dm, grocery_dm: self.grocery_dm, isAddGroceryViewOpened: self.$isAddGroceryViewOpened)
    }
}
}

struct DetailView: View {

@ObservedObject var grocery_dm : GroceryManager
@ObservedObject var food_dm : FoodManager

var grocery: Grocery

@State var isAddGroceryViewOpened = false

var body: some View {
    VStack {
    Text("Grocery: \(grocery.name)")
    Text("Foods: \(grocery.monday)")
    buttonEdit
    }
}

var buttonEdit: some View {
    Button(action: {
        self.isAddGroceryViewOpened = true
    }) {
        Text("Edit")
    }
    .sheet(isPresented: self.$isAddGroceryViewOpened) {
        AddGroceryView(food_dm: self.food_dm, grocery_dm: self.grocery_dm, isAddGroceryViewOpened: self.$isAddGroceryViewOpened, grocery: self.grocery)
    }
}
}

struct AddGroceryView: View {

@ObservedObject var food_dm : FoodManager
@ObservedObject var grocery_dm : GroceryManager

@State var selectFood = ""
@State var grocery_name : String = ""

@Binding var isAddGroceryViewOpened : Bool

var grocery : Grocery?

var body: some View {
    NavigationView {
        VStack {
            Form {
                TextField("Write a grocery", text: $grocery_name)
                monday_view(food_dm: self.food_dm, PickFood_String: self.$selectFood)
            }
            saveButton
        }
    }
    .onAppear {
        if let groceryOk = self.grocery {
            self.selectFood = groceryOk.monday
            self.grocery_name = groceryOk.name
        }
    }        
}

var saveButton: some View {
Button(action: {

    self.salva()
    self.isAddGroceryViewOpened = false
    })
     {
    Text("Save")
}
}

func salva() {
if !self.grocery_name.isEmpty && !self.selectFood.isEmpty {
        if let groceryOk = self.grocery {
            self.grocery_dm.editGrocery(id: groceryOk.id, name: self.grocery_name, monday: self.selectFood, tuesday: "", wednesday: "")
    } else {
            self.grocery_dm.newGrocery(name: self.grocery_name, monday: self.selectFood, tuesday: "", wednesday: "")
    }
        }
    self.isAddGroceryViewOpened = false
}
}

struct monday_view: View {
@State var isOn = false
@ObservedObject var food_dm : FoodManager
@Binding var PickFood_String: String
@State private var queryType: Int = 0

var body: some View {

    let binding = Binding<Int>(
        get: { self.queryType },
        set: {
            self.queryType = $0
            self.PickFood_String = self.food_dm.shoppingChart[self.queryType].name
    })

    return
        VStack {
            HStack(spacing: 20) {
                Text("Monday")
                    .multilineTextAlignment(.leading)

                Toggle(isOn: $isOn) {
                    Text("")
                    if(self.isOn) {
                        Picker(selection: binding, label: Text("")) {
                            ForEach(self.food_dm.shoppingChart.indices) { foods in
                                Text(self.food_dm.shoppingChart[foods].name).tag(foods)
                            }
                        }
                    }
                }
            }
     }
     }
     }
4

1 回答 1

0

尝试这个:

struct monday_view: View {
    @State var isOn = false
    @ObservedObject var food_dm : FoodManager
    @Binding var PickFood_String: String
    @State private var queryType: Int = 0

    var body: some View {

        let binding = Binding<Int>(
            get: { self.queryType },
            set: {
                self.queryType = $0
                self.PickFood_String = self.food_dm.shoppingChart[self.queryType].name
        })

        return
            VStack {

                VStack(spacing: 20) {
                    HStack {
                        Text("Monday")
                            .multilineTextAlignment(.leading)

                        Toggle(isOn: $isOn) {
                            Text("")

                        }
                    }
                    if(self.isOn) {
                        Picker(selection: binding, label: Text("")) {
                            ForEach(self.food_dm.shoppingChart.indices, id: \.self) { foods in

                                Text(self.food_dm.shoppingChart[foods].name).tag(foods)
                            }
                        }
                    }
                }
        }
    }
}
于 2020-04-08T11:52:44.760 回答