Published/Observed var not updating in view swiftui w/ calle



努力在swiftui中获得一个简单的示例:

  1. 加载默认列表视图(working)
  2. 点击按钮启动选择器/过滤选项(工作)
  3. 选择选项,然后点击按钮取消并呼叫所选选项的功能(通话正在进行)
  4. 显示从调用(不工作)返回的对象的新列表

我被困在#4,返回的查询没有使它到视图。我怀疑我在第3步调用时创建了一个不同的实例,但这对我来说没有意义,在哪里/如何/为什么这很重要。

我试图简化一些代码,但它仍然有点,抱歉。

感谢您的帮助!

带HStack的主视图和过滤器按钮:

import SwiftUI
import FirebaseFirestore
struct TestView: View {
@ObservedObject var query = Query()
@State var showMonPicker = false
@State var monFilter = "filter"

var body: some View {
VStack {
HStack(alignment: .center) {
Text("Monday")
Spacer()
Button(action: {
self.showMonPicker.toggle()
}, label: {
Text("(monFilter)")
})
}
.padding()

ScrollView(.horizontal) {
LazyHStack(spacing: 35) {
ForEach(query.queriedList) { menuItems in
MenuItemView(menuItem: menuItems)
}
}
}
}
.sheet(isPresented: $showMonPicker, onDismiss: {
//optional function when picker dismissed
}, content: {
CuisineTypePicker(selectedCuisineType: $monFilter)
})
}
}

Query()文件,调用具有所有结果的基本查询,以及返回特定结果的可选函数:

import Foundation
import FirebaseFirestore
class Query: ObservableObject {

@Published var queriedList: [MenuItem] = []

init() {
baseQuery()
}

func baseQuery() {
let queryRef = Firestore.firestore().collection("menuItems").limit(to: 50)

queryRef
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: (err)")
} else {
self.queriedList = querySnapshot?.documents.compactMap { document in
try? document.data(as: MenuItem.self)

} ?? []
}
}
}

func filteredQuery(category: String?, glutenFree: Bool?) {
var filtered = Firestore.firestore().collection("menuItems").limit(to: 50)
// Sorting and Filtering Data
if let category = category, !category.isEmpty {
filtered = filtered.whereField("cuisineType", isEqualTo: category)
}
if let glutenFree = glutenFree, !glutenFree {
filtered = filtered.whereField("glutenFree", isEqualTo: true)
}
filtered
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: (err)")
} else {
self.queriedList = querySnapshot?.documents.compactMap { document in
try? document.data(as: MenuItem.self);
} ?? []
print(self.queriedList.count)
}
}
}
}

我调用过滤查询的选择器视图:

import SwiftUI
struct CuisineTypePicker: View {

@State private var cuisineTypes = ["filter", "American", "Chinese", "French"]
@Environment(.presentationMode) var presentationMode
@Binding var selectedCuisineType: String
@State var gfSelected = false

let query = Query()

var body: some View {
VStack(alignment: .center) {
//Buttons and formatting code removed to simplify.. 
}
.padding(.top)

Picker("", selection: $selectedCuisineType) {
ForEach(cuisineTypes, id: .self) {
Text($0)
}
}
Spacer()
Button(action: {
self.query.filteredQuery(category: selectedCuisineType, glutenFree: gfSelected)

self.presentationMode.wrappedValue.dismiss()

}, label: {
Text( "apply filters")
})               
}
.padding()
}
}

我怀疑这个问题源于您的TestViewCuisineTypePicker之间没有共享相同的Query实例的事实。因此,当您在CuisineTypePicker中包含的实例上启动一个新的Firebase查询时,结果永远不会反映在主视图中。

这里有一个如何解决这个问题的例子(现在用一些非异步的示例代码替换了Firebase代码):

struct MenuItem : Identifiable {
var id = UUID()
var cuisineType : String
var title : String
var glutenFree : Bool
}
struct ContentView: View {
@ObservedObject var query = Query()
@State var showMonPicker = false
@State var monFilter = "filter"

var body: some View {
VStack {
HStack(alignment: .center) {
Text("Monday")
Spacer()
Button(action: {
self.showMonPicker.toggle()
}, label: {
Text("(monFilter)")
})
}
.padding()

ScrollView(.horizontal) {
LazyHStack(spacing: 35) {
ForEach(query.queriedList) { menuItem in
Text("(menuItem.title) - (menuItem.cuisineType)")
}
}
}
}
.sheet(isPresented: $showMonPicker, onDismiss: {
//optional function when picker dismissed
}, content: {
CuisineTypePicker(query: query, selectedCuisineType: $monFilter)
})
}
}
class Query: ObservableObject {

@Published var queriedList: [MenuItem] = []

private let allItems: [MenuItem] = [.init(cuisineType: "American", title: "Hamburger", glutenFree: false),.init(cuisineType: "Chinese", title: "Fried Rice", glutenFree: true)]

init() {
baseQuery()
}

func baseQuery() {
self.queriedList = allItems
}

func filteredQuery(category: String?, glutenFree: Bool?) {
queriedList = allItems.filter({ item in
if let category = category {
return item.cuisineType == category
} else {
return true
}
}).filter({item in
if let glutenFree = glutenFree {
return item.glutenFree == glutenFree
} else {
return true
}
})
}
}
struct CuisineTypePicker: View {
@ObservedObject var query : Query
@Binding var selectedCuisineType: String
@State private var gfSelected = false

private let cuisineTypes = ["filter", "American", "Chinese", "French"]
@Environment(.presentationMode) private var presentationMode

var body: some View {
VStack(alignment: .center) {
//Buttons and formatting code removed to simplify..
}
.padding(.top)

Picker("", selection: $selectedCuisineType) {
ForEach(cuisineTypes, id: .self) {
Text($0)
}
}
Spacer()
Button(action: {
self.query.filteredQuery(category: selectedCuisineType, glutenFree: gfSelected)
self.presentationMode.wrappedValue.dismiss()
}, label: {
Text( "apply filters")
})
}
}

相关内容

  • 没有找到相关文章