SwiftUI:如果从子视图触发时,父视图也可以弹出sheet,则不会呈现sheet。

3

假设我在NavigationView中有一个视图,带有前导和尾随按钮。 因为我可以从这个视图呈现两个不同的sheet,所以我使用了这样的枚举:

enum AccountActiveSheet {
   case about, settings
}

这个主视图中有两个 @State 属性,用于触发 sheet 的呈现。

@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")
    })
}

在导航视图的末尾,我选择正确的工作表进行呈现,就像这样。
.sheet(isPresented: $isSheetPresented) {
   self.activeSheet.sheet
}

它在模态视图中运行良好并呈现正确的视图。

但是,我还有多个子视图在此主视图中,当点击按钮时可以呈现出sheet。 在这种情况下,由子视图管理的sheet(即跟踪$isSheetPresented变量+由子视图提供的sheet内容)未被呈现。 没有任何反应。 看起来父视图的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")
        }
    }
}

1
提供的代码不足以重现您的情况。请提供完整的可重现示例吗? - Asperi
1
@Asperi,我更新了我的答案,包括完整的工作示例。请告诉我! - alpennec
我注意到这只发生在iOS 14.4上! - FarouK
1个回答

3
将根视图表单移出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
    }
}

1
这个为什么有效的解释(推测或其他)是什么? - smakus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接