As I understand the layout process in SwiftUI, most parent views by default only take up as much space as they need to fit their children. The following minimal example content view shows how the window will grow and shrink in response to populating a VStack
with Text Views:
struct ContentView: View {
@State var texts = ["text"]
var body: some View {
VStack {
Button("Add text") {
texts.append("text")
}
Button("Remove text") {
_ = texts.popLast()
}
ForEach(texts, id: \.self) { text in
Text(text)
}
}
}
}
Using the above ContentView, the window can't be manually resized.
A TabView
, however, doesn't seem to adhere to this behavior. When wrapping the VStack
above in a TabView
, the window will be manually resizable and the tab view always takes up the whole window. In particular, It doesn't grow if the VStack grows too large and it doesn't shrink when the VStack shrinks.
struct ContentView: View {
@State var texts = ["text"]
var body: some View {
TabView {
VStack {
Button("Add text") {
texts.append("text")
}
Button("Remove text") {
_ = texts.popLast()
}
ForEach(texts, id: \.self) { text in
Text(text)
}
}
.tabItem { Text("tabItem") }
}
}
}
I would like to have a TabView that behaves just like the VStack above, expanding and contracting in height based on its contents, and likewise causing the whole window to grow and shrink accordingly. Despite two hours of internet research I have failed to understand what determines this difference in behavior and how to fix it.
It is likely important to note that I am on macOS 10.15. To make the example content views work I have placed them in ContentView.swift of the template generated by Xcode for a macOS app with Interface set to "SwiftUI" and Life Cycle set to "AppKit App Delegate".