我正在創建一個功能,用戶可以在從我們的 API 中洗掉帖子后從陣列中洗掉它,我能夠成功地從陣列中洗掉正確的帖子,但我的 NewsFeed 視圖總是從視圖中洗掉錯誤的 PostCell,即使是正確的物件正在從陣列中洗掉???
NewsFeed 視圖似乎洗掉了串列中的最后一個 PostCell,而不是從陣列中成功洗掉的物件?
我正在通過列印出所有物件ID來檢查是否從視圖模型中洗掉了正確的物件,并且它肯定已經消失了。但是,Newsfeed 視圖洗掉了一個完全不同的視圖(最后一個),并且仍然顯示應該洗掉的視圖?
知道為什么會這樣嗎?
顯示所有帖子的新聞源視圖
struct NewsFeed: View {
@StateObject var newsfeedVM = NewsFeedViewModel()
var body: some View {
NavigationView {
List(0..<newsfeedVM.posts.count, id: \.self) { index in
PostCell(post: newsfeedVM.posts[index] )
}
}
}
}
查看模型
class NewsFeedViewModel: ObservableObject {
@Published var posts: [Post] = []
var subscriptions = Set<AnyCancellable>()
static let removePostFromArray = PassthroughSubject<String, Never>()
init() {
Self.removePostFromArray.sink { postId in
print(postId)
if let index = self.posts.firstIndex(where: { $0.id == postId }) {
// removes correct object
self.posts.remove(at: index)
// confirms correct object was removed
self.posts.forEach { post in
print(post.id)
}
}
}.store(in: &subscriptions)
}
}
每個帖子單元格都有一個用于洗掉帖子的操作表。
struct PostCell: View {
@StateObject var postVM = PostViewModel()
@State var post: Post
@State var showActionSheet: Bool = false
var body: some View {
VStack(spacing: 5) {
PostMedia(post: $post)
}
.actionSheet(isPresented: $showActionSheet) { "REPORT POST" }
}
// remove post with Combine
func reportPost(post: Post) {
NewsFeedViewModel.removePostFromArray.send(report.postId)
}
}
uj5u.com熱心網友回復:
這可以在沒有靜態成員和組合的情況下解決。我會向每個用戶傳遞一個閉包,PostCell這是用戶洗掉/報告帖子時執行的操作:
struct NewsFeed: View {
@StateObject var newsfeedVM = NewsFeedViewModel()
var body: some View {
NavigationView {
List(newsfeedVM.posts, id: \.id) { post in
PostCell(post: post, removePost: {vm.removePost(post.id)} ) // use the ID not the index
}
}
}
}
class NewsFeedViewModel: ObservableObject {
@Published var posts: [Post] = []
// var subscriptions = Set<AnyCancellable>()
// none of the static stuff: static let removePostFromArray = PassthroughSubject<String, Never>()
func removePost(id: Int) {
posts.removeAll(where: {$0.id == id})
}
}
struct PostCell: View {
@StateObject var postVM = PostViewModel()
@State var post: Post
@State var showActionSheet: Bool = false
var removePost: func () -> ()
var body: some View {
VStack(spacing: 5) {
PostMedia(post: $post)
}
.actionSheet(isPresented: $showActionSheet) { "REPORT POST" } // call report() here
}
// use a closure instead
func report() {
// not this: NewsFeedViewModel.removePostFromArray.send(report.postId)
removePost()
}
}
edit: if you want to have access to index, you can pass an array of tuples (index, item) to List (only tested this with ForEach. should work though):
List(Array(newsfeedVM.posts.enumerated()), id: \.index) { index, item in
// ... now you have both index and item. you use item to draw the views
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/437391.html
