Context
I have a Menu
(including multiple Buttons
) inside a SwiftUI
Toolbar
and a .sheet()
Modifier
inside the Toolbar
, too.
The problem is, that pressing the Button
with the show.toggle()
action does not present the Sheet
as expected.
Important: I noticed the weird behaviour, that when I give
showOption
an initial value likevar showOption: Option? = .option1
, this works perfectly fine (except the initialSheet
popup of course). However, once I initiate theshowOption
property withnil
, it breaks.
Code
struct MainView: View {
var showOption: Option?
// var showOption: Option? = .option -> this would work perfectly fine.
var body: some View {
NavigationStack {
Text("Hello World")
.toolbar {
ToolbarItem {
Menu {
... Button(action: { option = .option1 } { ... } ...
}
.sheet(item: $showOption) { option in
switch option {
case .option1: Text("Hello World 1")
...
}
}
}
}
}
}
}
Questions
- Is this caused by the
.sheet()
being inside theToolbar
or is there anything else I missed? - How can I solve this (ideally without moving the
.sheet()
outside of theToolbar
)?
3
Answers
if you move it outside of
Menu
(still in Toolbar) it works fine:In SwiftUI whenever we apply a modifier to view it actually create a new view with that change applied instead of modifying the existing view in the place. This behavior makes sense: our views only hold the exact properties we give them. Have a look at the sample code below.
Swift’s
type(of:)
method prints the exact type of a particular view/value, if we add the.sheet
modifier under the Menu,print(of:)
shows the following outputNests the elements in the following way:
Text -> ToolbarModifier -> TupleToolbarContent -> ToolbarItem ->
ModifiedContent -> Menu -> Text -> Button -> SheetPresentationModifier
if we add the
.sheet
modifier under the buttonprint(of:)
shows the following outputNest the elements in the following way:
Text -> ToolbarModifier -> TupleToolbarContent -> ToolbarItem -> Menu -> Text -> ModifiedContent -> Button -> SheetPresentationModifier
So, as we discussed earlier that the order of modifier effect on the functionality of SwiftUI. If we add
.sheet
to the Menu element then it would have additional functionality or appearance that is specific to the ModifiedContent and shows the sheet. While for the case of button ModifiedContent does not work.The answer is still the same and it still works, if you move
.sheet
out of theMenu
: