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



这段小代码显示了API中的文章,其中有2列ArticleView上的scrollview。不幸的是,在第六次loadMoreContentIfNeeded之后,我很难处理这个错误

线程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或Array中。您正在通过id: .1.article_id识别内容。然而,我想!在您的数组中,有一些项目具有相同的文章id。LazyVGrid要求您的内容具有明确的唯一id,而VStack没有。

由于我不知道您的Array或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〃;它会很好用的。

最新更新