'SwiftUI Table error: The compiler is unable to type-check this expression in reasonable time
I have a very strange situation happening in my code (SwiftUI, macOS app), which doesn't make sense to me. The following builds and runs as expected:
private var bodySongs: some View {
Table(musicLibraryProvider.filtered(by: searchTerm), selection: $selectedSongID) {
// TableColumn("") {
// Image(nsImage: $0.artwork?.image ?? NSImage(named: "EmptyAlbum")!)
// .resizable()
// .aspectRatio(contentMode: .fit)
// .frame(width: 22.5, height: 22.5)
// .clipShape(RoundedRectangle(cornerRadius: 2))
// .overlay(RoundedRectangle(cornerRadius: 2).stroke(Color.gray, lineWidth: 0.5))
// }.width(22.5)
TableColumn("Title") {
Text($0.title)
}
TableColumn("Artist") {
Text($0.artist?.name ?? "")
}
TableColumn("Album") {
Text($0.album.title ?? "")
}
TableColumn("Year") {
Text("\($0.year)")
}
}
.navigationTitle("Songs")
}
If I uncomment the image column, it throws this error when compiling:
The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
But if I comment out the next two columns, it compiles and runs:
private var bodySongs: some View {
Table(musicLibraryProvider.filtered(by: searchTerm), selection: $selectedSongID) {
TableColumn("") {
Image(nsImage: $0.artwork?.image ?? NSImage(named: "EmptyAlbum")!)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 22.5, height: 22.5)
.clipShape(RoundedRectangle(cornerRadius: 2))
.overlay(RoundedRectangle(cornerRadius: 2).stroke(Color.gray, lineWidth: 0.5))
}.width(22.5)
// TableColumn("Title") {
// Text($0.title)
// }
// TableColumn("Artist") {
// Text($0.artist?.name ?? "")
// }
TableColumn("Album") {
Text($0.album.title ?? "")
}
TableColumn("Year") {
Text("\($0.year)")
}
}
.navigationTitle("Songs")
}
In other words, these three columns cannot exist at the same time. Does anyone knows why?
Solution 1:[1]
It's best not to do any computation inside body because it has to run as fast as possible for SwiftUI to work correctly. You can resolve this by just reading from a property that already has the data in a filtered state.
You can use one of the side-effect modifiers to achieve this, like onAppear, onChange or even .task(id:searchTerm) if you'd like to do the work of using the current search term to update an @State var with the filtered results asynchronously.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | malhal |
