They are not empty cells. The List
just fills all available space and draws empty rows placeholders where there is no content. In your scenario is needed to limit height of List
to its content.
Here is a solution. Tested with Xcode 11.4 / iOS 13.4
For better visibility let's separate your list into own view named CovidDataList
, then here is in your provided body
:
//List to Initialize TableView Data
CovidDataList(covid: self.covid)
}//END List
Note1: The height of list updated in run-time so should be tested in running application (not in Preview)
Note2: I tested with replicated cover data model so some adapting might be needed to your code
struct CovidDataList: View {
@Environment(.defaultMinListRowHeight) var minRowHeight
let covid: [CovidData]
@State private var listHeight = CGFloat.infinity
var body: some View {
List {
ForEach(covid, id: .self) { covidData in
HStack {
Image(systemName: "photo")
.padding()
HStack {
Text("Title").frame(maxWidth: .infinity, alignment: .leading)
Text("Value")
.font(.subheadline)
.frame(maxWidth: .infinity, alignment: .trailing)
}
}
.listRowInsets(EdgeInsets()).padding(.horizontal)
}
.anchorPreference(key: BoundsPreferenceKey.self, value: .bounds) { [$0] }
}
.backgroundPreferenceValue(BoundsPreferenceKey.self) { rects in
GeometryReader { gp in
self.updateListFrame(gp: gp, anchors: rects)
}
}.frame(maxHeight: listHeight)
}
private func updateListFrame(gp: GeometryProxy, anchors: [Anchor<CGRect>]) -> some View {
let contentHeight = anchors.reduce(CGFloat.zero) { $0 + gp[$1].size.height }
DispatchQueue.main.async { // << required !!
self.listHeight = max(contentHeight, self.minRowHeight * CGFloat(self.covid.count))
}
return Color.clear
}
}
Note: BoundsPreferenceKey
is taken from this my answer
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…