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

u3r8eeie  于 2022-11-18  发布在  Mac
关注(0)|答案(1)|浏览(119)

我试图创建一个视图,它根据用户是否切换收藏按钮来更新。我希望整个视图都能重建,以便在值数组发生变化时显示值数组。在视图内部,一个for each循环应该显示数组中的每个值。
每次savedArray更改时,我想要更新的视图是FavView。(我将其创建为@Published,以便视图可以重建),它会给我一个错误:泛型结构“ForEach”要求“Published〈[String]〉.Publisher”符合“RandomAccessCollection”。我很困惑,因为我认为字符串数组可以在for each循环中使用。这不是真的吗?我如何循环@Published数组?谢谢!这是我的savedArray代码(在ViewModel中)和FavView代码,我想用for each在其中显示它。

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

xghobddn1#

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

这应该可以。

相关问题