I have a main view with a fixed width and height because this view will be converted into a PDF. Next, I have an array of subviews that will be vertically stacked in the main view. There may be more subviews available than can fit in the main view so I need a way to make sure that I don't exceed the main view's total height. For example, if I have eight subviews in my array but only three will fit into the main view, then I need to stop adding subviews after three. The remaining subviews will start the process over on a new main view.
My problem is, if I use GeometryReader to get the height of a view, first I have to add it. But once the view is added, it’s too late to find out if it exceeded the total height available.
Below shows how I get the height of each view as it's being added. Which is not much to go on, I know, but I'm pretty stuck.
Update: My current strategy is to create a temporary view where I can add subviews and return an array with only the ones that fit.
struct PDFView: View {
var body: some View {
VStack {
ForEach(tasks) { task in
TaskRowView(task: task)
.overlay(
GeometryReader { geo in
// geo.size.height - to get height of current view
})
}
}
.layoutPriority(1)
}
}
A possible solution is to use View Preferences.
You can calculate the total height of your items and in
onPreferenceChange
increase theircount
by 1 (until thetotalHeight
reachesmaxHeight
).Here is the full implementation:
PreferenceKey
for retrieving view height:TaskRowView
(of any height):PreferenceKey
in your view: