Hi, colleagues: I've spent days trying to understand this little SwiftUI layout problem, and I've made a minimal test app to explain it. It's based on a Content View of a fixed size.
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.windowResizability(.contentSize)
.windowToolbarStyle(.unified(showsTitle: false))
}
}
struct ContentView: View {
let complaint = """
What's with the vertical space \
around me when I'm \
in a detail column?
"""
var body: some View {
Text(complaint)
.font(.title)
.frame(width: 300, height: 300)
.background(.blue)
}
}
And here's the result. As expected, the Content View is hugged nicely by the window:
My goal is to place a fixed-size view like this in the detail column of a Navigation Split View. So I update the scene's root view:
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
NavigationSplitView(
sidebar: {
},
detail: {
ContentView()
}
)
}
.windowResizability(.contentSize)
.windowToolbarStyle(.unified(showsTitle: false))
}
}
struct ContentView: View {
let complaint = """
What's with the vertical space \
around me when I'm \
in a detail column?
"""
var body: some View {
Text(complaint)
.font(.title)
.frame(width: 300, height: 300)
.background(.blue)
}
}
And we get the following. This is the window at its minimum size:
I expected the Content View to fit perfectly within the detail column, but as you can see, we have mysterious vertical spaces above and below it. My first guess was that these spaces were some kind of context-dependent default padding. Eventually, I noticed the combined heights of the mysterious spaces equalled the height of the toolbar. I even checked this by using other toolbar styles with different heights – the spaces always adjusted to equal the toolbar's height.
At this point, I was guessing this had something to do with the "safe area" – macOS sometimes treats the toolbar as an area underneath which content can lie, so it might be well-meaningly but redundantly adding the toolbar's height to the detail area or something, and there might be some modifier that will opt out of that behaviour; perhaps ignoresSafeArea()
. But nothing I've tried has helped.
I've tried a number of other solutions, but none is ideal, and none help me understand why SwiftUI is adding this vertical space to begin with. Any insight would be very much appreciated.