You didn't include it in your question but I guess the error you're getting when going without the stack is the following?
Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type
The error gives you a good hint of what's going on but in order to understand it, you need to understand the concept of opaque return types. That's how you call the types prefixed with the some
keyword. I didn't see any Apple engineers going deep into that subject at WWDC (maybe I missed the respective talk?), which is why I did a lot of research myself and wrote an article on how these types work and why they are used as return types in SwiftUI.
There is also a detailed technical explanation in another
If you want to fully understand what's going on I recommend reading both.
As a quick explanation here:
General Rule:
Functions or properties with an opaque result type (some Type
)
must always return the same concrete type.
In your example, your body
property returns a different type, depending on the condition:
var body: some View {
if someConditionIsTrue {
TabView()
} else {
LoginView()
}
}
If someConditionIsTrue
, it would return a TabView
, otherwise a LoginView
. This violates the rule which is why the compiler complains.
If you wrap your condition in a stack view, the stack view will include the concrete types of both conditional branches in its own generic type:
HStack<ConditionalContent<TabView, LoginView>>
As a consequence, no matter which view is actually returned, the result type of the stack will always be the same and hence the compiler won't complain.
Supplemental:
There is actually a view component SwiftUI provides specifically for this use case and it's actually what stacks use internally as you can see in the example above:
It has the following generic type, with the generic placeholder automatically being inferred from your implementation:
ConditionalContent<TrueContent, FalseContent>
I recommend using that view container rather that a stack because it makes its purpose semantically clear to other developers.