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
    }
}