如何使'Published<[String]>.Publisher'符合'RandomAccessCollection'



我正在尝试创建一个视图,根据用户是否切换收藏夹按钮进行更新。我希望重建整个视图,以便在值数组发生更改时显示值数组。在视图中,for each循环应该显示数组中的每个值。

每次savedArray更改时,我要更新的视图是FavView。但是,当我尝试使用foreach循环来显示每个值都是savedArray(我将其创建为@Published,以便重建视图(时,它会给我一个错误Generic结构"foreach"要求"Published<[String]>。发布服务器"符合"RandomAccessCollection"。我很困惑,因为我认为字符串数组可以用于每个循环。这不是真的吗?如何在@Published数组中循环?非常感谢。这是我为savedArray(在ViewModel中(和FavView编写的代码,我想将其显示在其中。

struct ContentView: View {
@StateObject private var statNavManager = StatsNavigationManager()
@State private var saved: [String] = []
var body: some View {
TabView {

StatsView(saved: $saved)
.tabItem {
Label("Home", systemImage: "house")
}
FavView(saved: $saved)
.tabItem {
Label("Saved", systemImage: "bookmark")
}
}
.environmentObject(statNavManager)
}
}
final class ViewModel: ObservableObject {
@Published var items = [Item]()
@Published var showingFavs = true
@Published var savedItems: Set<String> = []
@Published var savedArray: [String]
// Filter saved items

var filteredItems: [String]  {
//return self.items
return savedArray
}
var db = Database()

init() {
self.savedItems = db.load()
self.items = db.returnList()//the items
self.savedArray = Array(db.load())
print("savedarray", savedArray)
print("important!", self.savedItems, self.items)
}

func contains(_ item: Item) -> Bool {
savedItems.contains(item.id)
}

// Toggle saved items
func toggleFav(item: Item) {
print("Toggled!", item)
if contains(item) {
savedItems.remove(item.id)
if let index = savedArray.firstIndex(of: item.id) {
savedArray.remove(at: index)
}
} else {
savedItems.insert(item.id)
savedArray.append(item.id)
}
db.save(items: savedItems)
}
}

struct FavView: View {
@StateObject private var vm = ViewModel()
var body: some View {
VStack {

List {
var x = print("testing",vm.savedArray)//this only prints once at the start
ForEach($vm.savedArray, id: .self) { string in
let item = vm.db.returnItem(input: string.wrappedValue)
HStack {
VStack(alignment: .leading) {
Text(item.title)
.font(.headline)

Text(item.description)
.font(.subheadline)
}
Spacer()
Image(systemName: vm.contains(item) ? "bookmark.fill" : "bookmark")
.foregroundColor(.blue)
.onTapGesture {
vm.toggleFav(item: item)
}
}
}
}
.cornerRadius(10)
}
}
}

ForEach中,如果使用$符号访问savedArray,则必须使用vm本身

struct FavView: View {
@StateObject private var vm = ViewModel()

var body: some View {
VStack {

List {

ForEach($vm.savedArray, id: .self) { string in //< here $vm.savedArray not vm.$savedArray
let item = vm.db.returnItem(input: string)
HStack {
VStack(alignment: .leading) {
Text(item.title)
.font(.headline)

Text(item.description)
.font(.subheadline)
}
Spacer()
Image(systemName: vm.contains(item) ? "bookmark.fill" : "bookmark")
.foregroundColor(.blue)
.onTapGesture {
vm.toggleFav(item: item)
}
}
}
}
.cornerRadius(10)
}
}
}

这应该行得通。

最新更新