在使用 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)
}
}
}
}
}
}
}
}