[英]Why does .sheet(item) Modifier not work inside Toolbar in SwiftUI?
Context语境
I have a Menu
(including multiple Buttons
) inside a SwiftUI
Toolbar
and a .sheet()
Modifier
inside the Toolbar
, too.我在
SwiftUI
Toolbar
内有一个Menu
(包括多个Buttons
),在Toolbar
内也有一个.sheet()
Modifier
。
The problem is, that pressing the Button
with the show.toggle()
action does not present the Sheet
as expected.问题是,使用
show.toggle()
操作按下Button
不会按预期显示工作Sheet
。
Important: I noticed the weird behaviour, that when I give
showOption
an initial value likevar showOption: Option? =.option1
重要提示:我注意到奇怪的行为,当我给
showOption
一个初始值时,比如var showOption: Option? =.option1
var showOption: Option? =.option1
, this works perfectly fine (except the initialSheet
popup of course).var showOption: Option? =.option1
,这工作得很好(当然初始工作Sheet
弹出窗口除外)。 However, once I initiate theshowOption
property withnil
, it breaks.但是,一旦我使用
nil
启动showOption
属性,它就会中断。
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问题
.sheet()
being inside the Toolbar
or is there anything else I missed?Toolbar
栏内的.sheet()
引起的,还是我遗漏了其他任何内容?.sheet()
outside of the Toolbar
)?.sheet()
移到Toolbar
之外)? if you move it outside of Menu
(still in Toolbar) it works fine:如果你将它移出
Menu
(仍在工具栏中)它工作正常:
struct ContentView: View {
@State private var show: Bool = false
var body: some View {
NavigationStack {
Text("Hello World")
.toolbar {
ToolbarItem {
Menu("Test") {
Button("Show") {
show.toggle()
}
}
.sheet(isPresented: $show) {
Text("Hello World 2")
}
}
}
}
}
}
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.在 SwiftUI 中,每当我们应用修饰符来查看它时,它实际上会创建一个应用了该更改的新视图,而不是修改该位置的现有视图。 This behavior makes sense: our views only hold the exact properties we give them.
这种行为是有道理的:我们的视图只保留我们赋予它们的确切属性。 Have a look at the sample code below.
看看下面的示例代码。
struct ContentView: View {
@State private var show: Bool = false
var body: some View {
NavigationStack {
Text("Hello World")
.toolbar {
ToolbarItem {
Menu("Test") {
Button("Show") {
print(type(of: self.body))
show.toggle()
}
}
.sheet(isPresented: $show) {
Text("Hello World 2")
}
}
}
}
}
}
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 output Swift 的
type(of:)
方法打印特定视图/值的确切类型,如果我们在Menu下添加.sheet
修饰符, print(of:)
显示以下内容 output
ModifiedContent<Text, ToolbarModifier<(), TupleToolbarContent<ToolbarItem<(), ModifiedContent<Menu<Text, Button>, SheetPresentationModifier>>>>>
ModifiedContent<Text, ToolbarModifier<(), TupleToolbarContent<ToolbarItem<(), ModifiedContent<Menu<Text, Button>, SheetPresentationModifier>>>>>>
Nests the elements in the following way: Text -> ToolbarModifier -> TupleToolbarContent -> ToolbarItem -> ModifiedContent -> Menu -> Text -> Button -> SheetPresentationModifier
按以下方式嵌套元素:Text -> ToolbarModifier -> TupleToolbarContent -> ToolbarItem ->
ModifiedContent -> Menu -> Text -> Button -> SheetPresentationModifier
if we add the .sheet
modifier under the button print(of:)
shows the following output如果我们在按钮
print(of:)
下添加.sheet
修饰符,则显示以下 output
ModifiedContent<Text, ToolbarModifier<(), TupleToolbarContent<ToolbarItem<(), Menu<Text, ModifiedContent<Button, SheetPresentationModifier>>>>>
ModifiedContent<Text, ToolbarModifier<(), TupleToolbarContent<ToolbarItem<(), Menu<Text, ModifiedContent<Button, SheetPresentationModifier>>>>>>
Nest the elements in the following way: Text -> ToolbarModifier -> TupleToolbarContent -> ToolbarItem -> Menu -> Text -> ModifiedContent -> Button -> SheetPresentationModifier按以下方式嵌套元素: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.因此,正如我们之前讨论的那样,修饰符的顺序会影响 SwiftUI 的功能。如果我们将
.sheet
添加到Menu元素,那么它将具有特定于 ModifiedContent 的附加功能或外观并显示工作表。 While for the case of button ModifiedContent does not work.而对于按钮ModifiedContent 的情况不起作用。
The answer is still the same and it still works, if you move .sheet
out of the Menu
:如果您将
.sheet
移出Menu
,答案仍然相同并且它仍然有效:
enum Option: Int, Identifiable {
case option1 = 1
case option2 = 2
case option3 = 3
var id: Int { self.rawValue }
}
struct ContentView: View {
@State private var showOption: Option?
var body: some View {
NavigationStack {
Text("Hello World")
.toolbar {
ToolbarItem {
Menu("Menu") {
Button("1") { showOption = .option1 }
Button("2") { showOption = .option2 }
Button("3") { showOption = .option3 }
}
.sheet(item: $showOption) { option in
Text("Hello World \(option.rawValue)")
}
}
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.