Обновить средство выбора (SwiftUI) - PullRequest
0 голосов
/ 08 апреля 2020

Я хотел бы предоставить пользователю возможность выбора после выбора его с помощью AddView. EditView, запущенный DetailView, показывает, что текстовое поле заполнено, но средство выбора по-прежнему пусто, хотя я уже выбрал элемент.

Я создал две модели (обе являются идентифицируемыми, кодируемыми, уравниваемыми, хэш-данными), которые относятся к 2 массивам:

  • Бакалея (модель) ---> продукты (массив)
  • Еда (модель) ----> shoppingChart (массив)

Моя цель - добавить новый продукт, присвоив ему имя и выбрав продукт, хранящийся в корзине покупок, из подборщика. Я использовал AddView для хранения продуктов и EditButton внутри DetailView для редактирования сохраненных данных. Я использовал Toggle «если», чтобы активировать сборщик.

Вот код:

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)
                            }
                        }
                    }
                }
            }
     }
     }
     }

1 Ответ

0 голосов
/ 08 апреля 2020

попробуйте это:

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)
                            }
                        }
                    }
                }
        }
    }
}
...