SwiftUI:sheet 如果从子视图触发则不显示,而父视图也可以显示 sheet
SwiftUI: sheet not presented if triggered from subview when superview can also present sheet
假设我在 NavigationView 中有一个视图,带有前导和尾随按钮。
因为我可以从这个视图中呈现两个不同的 sheet,所以我使用这样的枚举:
enum AccountActiveSheet {
case about, settings
}
此主视图在视图中有两个 @State 属性来触发 sheet 演示文稿。
@State private var isSheetPresented: Bool = false
@State private var activeSheet: AccountActiveSheet = .about
每个按钮可以触发一个sheet。
var aboutButton: some View {
Button(action: {
self.activeSheet = .about
self.isSheetPresented.toggle()
}, label: {
Image(systemName: "info.circle.fill")
})
}
在导航视图的末尾,我 select 正确的 sheet 就这样呈现
.sheet(isPresented: $isSheetPresented) {
self.activeSheet.sheet
}
它工作正常,并在模态中呈现正确的视图。
但是我在这个主视图中也有多个子视图,可以在点击按钮时显示 sheets。在这种情况下,不显示由子视图管理的 sheet(即用于跟踪 $isSheetPresented + 子视图提供的 sheet 内容的 @State 变量)。什么都没发生。似乎 superview sheet 修饰符阻止子视图呈现 sheet.
是否可以让父视图和子视图同时管理 sheet 演示文稿?
enum AccountActiveSheet {
case about, settings
@ViewBuilder
var sheet: some View {
switch self {
case .about: Text("About")
case .settings: Text("Settings")
}
}
}
struct AccountView: View {
@State private var isSheetPresented: Bool = false
@State private var activeSheet: AccountActiveSheet = .about
var aboutButton: some View {
Button(action: {
self.activeSheet = .about
self.isSheetPresented.toggle()
}, label: {
Image(systemName: "info.circle.fill")
})
}
var settingsButton: some View {
Button(action: {
self.activeSheet = .settings
self.isSheetPresented.toggle()
}, label: {
Image(systemName: "gearshape.fill")
})
}
var body: some View {
NavigationView {
VStack {
Subview()
}
.navigationBarTitle("Account", displayMode: .inline)
.navigationBarItems(leading: aboutButton, trailing: settingsButton)
.sheet(isPresented: $isSheetPresented) {
self.activeSheet.sheet
}
}
}
}
struct Subview: View {
@State var isSheetPresented: Bool = false
var body: some View {
Button("Present sheet") {
self.isSheetPresented.toggle()
}
.sheet(isPresented: $isSheetPresented) {
Text("Subview")
}
}
}
将根视图 sheet 移出 NavigationView
(使用 Xcode 12.1 / iOS 14.1 测试)
var body: some View {
NavigationView {
VStack {
Subview()
}
.navigationBarTitle("Account", displayMode: .inline)
.navigationBarItems(leading: aboutButton, trailing: settingsButton)
}
.sheet(isPresented: $isSheetPresented) { // << here !!
self.activeSheet.sheet
}
}
假设我在 NavigationView 中有一个视图,带有前导和尾随按钮。 因为我可以从这个视图中呈现两个不同的 sheet,所以我使用这样的枚举:
enum AccountActiveSheet {
case about, settings
}
此主视图在视图中有两个 @State 属性来触发 sheet 演示文稿。
@State private var isSheetPresented: Bool = false
@State private var activeSheet: AccountActiveSheet = .about
每个按钮可以触发一个sheet。
var aboutButton: some View {
Button(action: {
self.activeSheet = .about
self.isSheetPresented.toggle()
}, label: {
Image(systemName: "info.circle.fill")
})
}
在导航视图的末尾,我 select 正确的 sheet 就这样呈现
.sheet(isPresented: $isSheetPresented) {
self.activeSheet.sheet
}
它工作正常,并在模态中呈现正确的视图。
但是我在这个主视图中也有多个子视图,可以在点击按钮时显示 sheets。在这种情况下,不显示由子视图管理的 sheet(即用于跟踪 $isSheetPresented + 子视图提供的 sheet 内容的 @State 变量)。什么都没发生。似乎 superview sheet 修饰符阻止子视图呈现 sheet.
是否可以让父视图和子视图同时管理 sheet 演示文稿?
enum AccountActiveSheet {
case about, settings
@ViewBuilder
var sheet: some View {
switch self {
case .about: Text("About")
case .settings: Text("Settings")
}
}
}
struct AccountView: View {
@State private var isSheetPresented: Bool = false
@State private var activeSheet: AccountActiveSheet = .about
var aboutButton: some View {
Button(action: {
self.activeSheet = .about
self.isSheetPresented.toggle()
}, label: {
Image(systemName: "info.circle.fill")
})
}
var settingsButton: some View {
Button(action: {
self.activeSheet = .settings
self.isSheetPresented.toggle()
}, label: {
Image(systemName: "gearshape.fill")
})
}
var body: some View {
NavigationView {
VStack {
Subview()
}
.navigationBarTitle("Account", displayMode: .inline)
.navigationBarItems(leading: aboutButton, trailing: settingsButton)
.sheet(isPresented: $isSheetPresented) {
self.activeSheet.sheet
}
}
}
}
struct Subview: View {
@State var isSheetPresented: Bool = false
var body: some View {
Button("Present sheet") {
self.isSheetPresented.toggle()
}
.sheet(isPresented: $isSheetPresented) {
Text("Subview")
}
}
}
将根视图 sheet 移出 NavigationView
(使用 Xcode 12.1 / iOS 14.1 测试)
var body: some View {
NavigationView {
VStack {
Subview()
}
.navigationBarTitle("Account", displayMode: .inline)
.navigationBarItems(leading: aboutButton, trailing: settingsButton)
}
.sheet(isPresented: $isSheetPresented) { // << here !!
self.activeSheet.sheet
}
}