This used to work fine before but since Xcode 14 if I use an AsyncImage inside a Button or NavigationLink in my list the image loads the first time but when the cell is reused it only displays the placeholder.
Two things I noticed:
- clicking on the button immediately fixes the image in that cell
- If I remove the Button and add the view with the AsyncImage directly in the ForEach the problem disappears
Code example:
import SwiftUI
struct ContentView: View {
@StateObject var viewModel = ItemListViewModel()
var body: some View {
List {
ForEach(viewModel.items, id: \.self) { item in
Button {
} label: {
HStack {
AsyncImage(url: URL(string: "https://www.appatar.io/com.facebook.Facebook")) { phase in
if let image = phase.image {
// SHOW IMAGE
image
.resizable()
.frame(width: 40, height: 40)
} else if phase.error != nil {
// FAILED
HStack {
Image(systemName: "exclamationmark.triangle")
Text(phase.error?.localizedDescription ?? "")
}
.padding()
} else {
// LOADING
Color.red
.frame(width: 40, height: 40)
}
}
Text("Item #\(item)")
}
.padding()
}
}
Section {
ProgressView()
.onAppear {
viewModel.retrieveDataFromAPI()
}
}
.navigationBarTitle("Pagination Test")
}
}
}
class ItemListViewModel: ObservableObject {
@Published var items: [Int] = []
func retrieveDataFromAPI(completion: (() -> Void)? = nil) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
guard let self = self else { return }
let newData = Array(self.items.count...(self.items.count + 50))
self.items.append(contentsOf: newData)
completion?()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}