SwiftUI线程1:致命错误:每个布局项只能出现一次

这个小的代码是从2列与API的文章scrollviewArticleView。不幸的是,在第 6loadMoreContentIfNeeded次之后,这个错误让我很难受

线程 1:致命错误:每个布局项只能出现一次

我曾尝试添加.id(UUID())我的代码以避免 id 问题,但它也没有帮助。我还观察到此错误也发生在 LazyVStavk 中。如果将 LazyVStack 更改为 VStack,则不会出现此问题。但是 SwiftUI 中没有任何东西叫做VGrid.

struct ArticleView: View {
@ObservedObject var service = ArticleService()
let columns: [GridItem] = Array(repeating: GridItem(.flexible(), spacing: 0), count: 2)
var body: some View {     
ScrollView(.vertical, showsIndicators: false) {
                        LazyVGrid(columns: columns, spacing:0) {
                            ForEach(Array(service.articlePost.enumerated()), id: .1.article_id) { i, post in
                                ArticleListElementView(articlePost: post, cellNumber: i)
                                    .id(UUID())
                                    .onAppear {
                                        self.service.loadMoreContentIfNeeded(currentItem: post)
                                    }
                                    .padding(.all, 20)
                                    .onTapGesture {
                                        self.shown = true
                                        self.selectedArticle = post
                                    }
                               }
                          }
                     }

 private func loadMoreContent() {
    
    guard !isLoadingPage && canLoadMorePages else {
        return
    }
    isLoadingPage = true
    
    let parameters = ["index": "articles", "start" : "(currentPage)"]
    if let url = URL(string: "http:/v2/search/") {
        let session = URLSession(configuration: .default)
        var request = URLRequest(url:url)
        request.httpMethod = "POST"
        
        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
        } catch let error {
            print(error.localizedDescription)
        }
        
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        
        session.dataTaskPublisher(for: request as URLRequest)
            .map(.data)
            .decode(type: ArticleResults.self, decoder: JSONDecoder())
            .receive(on: DispatchQueue.main)
            .handleEvents(receiveOutput: { response in
                self.isLoadingPage = false
                self.currentPage += 1
            })
            .map({ response in
                return self.articlePost + response.articles
            })
            .catch({ _ in Just(self.articlePost) })
            .assign(to: &$articlePost)
    }
    
}

func loadMoreContentIfNeeded(currentItem item: ArticlePost?) {
    guard let item = item else {
        loadMoreContent()
        return
    }
    
    let thresholdIndex = articlePost.index(articlePost.endIndex, offsetBy: -5)
    if articlePost.firstIndex(where: { $0.id == item.id }) == thresholdIndex {
        loadMoreContent()
    }
}

回答

我只能指出您的问题,因为仍然缺少一些相关代码。

问题在于您的 ForEach 或您的数组。您正在通过 识别内容id: .1.article_id。不过,我猜!在您的数组中有具有相同文章 ID 的项目。LazyVGrid要求您的内容具有明确的 unique id,而VStack没有。

由于我不知道您的数组或loadMoreContentIfNeeded函数,因此我无法指出您为什么存在重复项的问题。

这是一个示例,向您展示差异:

这会崩溃,因为服务包含两次“Test123”并且您通过它们的内容识别它

struct ContentView: View {
    var service = ["Test123", "Test1235", "Test123", "dasdkjasdkas"]
    let columns: [GridItem] = Array(repeating: GridItem(.flexible(), spacing: 0), count: 2)
    
    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {
            LazyVGrid(columns: columns, spacing:0) {
                ForEach(service, id: .self) { element in
                    Text(element)
                        .id(UUID())
                        .onAppear {
                            //self.service.loadMoreContentIfNeeded(currentItem: post)
                        }
                        .padding(.all, 20)
                        .onTapGesture {
                            //self.shown = true
                            //self.selectedArticle = post
                        }
                }
            }
        }
    }
}

删除一个“Test123”,它会正常工作。


以上是SwiftUI线程1:致命错误:每个布局项只能出现一次的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>