从子视图呈现模态视图表

时间:2021-01-12 01:47:02

标签: ios swift swiftui

我正在尝试从导航栏上的菜单项中选择的子视图中显示工作表,但没有显示模式工作表。我花了几天时间尝试调试,但无法指出问题所在。

对不起,这有点令人困惑,将显示要重现的代码的简化版本。但简而言之,问题似乎是我作为主视图的一部分的工作表视图。从主视图中删除工作表代码会显示子视图中的工作表。不幸的是,我没有更改 Mainview.swift 的自由

让我展示一些代码以使其易于理解....

首先,在展示代码之前,重复问题的步骤:

  1. 点击导航栏中带有 3 个点的圆圈
  2. 选择第二项(子视图)
  3. 单击“编辑参数”按钮,将不显示 EditParameters() 视图

ContentView.swift(只调用 Mainview())。包含要复制以复制问题的代码:-)

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                Mainview()
            }
        }
    }
}

主视图.swift。这是实际应用程序的简化版本,它非常复杂,不幸的是,我在这里没有太多改变的余地!

fileprivate enum CurrentView {
    case summary, sub
}
enum OptionSheet: Identifiable {
    var id: Self {self}
    case add
}
struct Mainview: View {
    @State private var currentView: CurrentView? = .summary
    @State private var showSheet: OptionSheet? = nil

    var body: some View {
        GeometryReader { g in
            content.frame(width: g.size.width, height: g.size.height)
                .navigationBarTitle("Main", displayMode: .inline)
        }
        //Removing the below sheet view will display the sheet from the subview but with this sheet here, it the sheet from subview does not work. This is required as these action items are accessed from the second menu item (circle and arrow) navigation baritem
        .sheet(item: $showSheet, content: { mode in
            sheetContent(for: mode)
        })
        .toolbar {
            HStack {
                trailingBarItems
                actionItems
            }
        }
    }
    
    var actionItems: some View {
        Menu {
            Button(action: {
                showSheet = .add
            }) {
                Label("Add Elements", systemImage: "plus")
            }
        } label: {
            Image(systemName: "cursorarrow.click").resizable()
            
        }
        
    }

    var trailingBarItems: some View {
        Menu {
            Button(action: {currentView = .summary}) {
                Label("Summary", systemImage: "list.bullet.rectangle")
            }
            Button(action: {currentView = .sub}) {
                Label("Subview", systemImage: "circle")
            }
        } label: {
            Image(systemName: "ellipsis.circle").resizable()
        }
    }
    
    @ViewBuilder
    func sheetContent(for mode: OptionSheet) -> some View {
        switch mode {
        case .add:
            AddElements()
        }
    }
    
    @ViewBuilder
    var content: some View {
        if let currentView = currentView {
            switch currentView {
            case .summary:
                SummaryView()
            case .sub:
                SubView()
            }
        }
    }
}

Subview.swift。这是包含不显示工作表的“编辑参数”按钮的文件。我正在尝试从此视图显示工作表。

struct SubView: View {
    @State private var editParameters: Bool = false
    var body: some View {
        VStack {
            Button(action: {
                editParameters.toggle()
            }, label: {
                HStack {
                    Image(systemName: "square.and.pencil")
                        .font(.headline)
                    Text("Edit Parameters")
                        .fontWeight(.semibold)
                        .font(.headline)
                }
            })
            .padding(10)
            .foregroundColor(Color.white)
            .background(Color(.systemBlue))
            .cornerRadius(20)
            .sheet(isPresented: $editParameters, content: {
                EditParameterView()
            })
            .padding()
            Text("Subview....")
        }
        .padding()
    }
}

EditParameters.swift。这是按下“编辑参数”按钮时应显示的视图

struct EditParameterView: View {
    var body: some View {
        Text("Edit Parameters...")
    }
}

Summaryview.swift。这里没什么特别的。只是为了完整性而包括

struct SummaryView: View {
    var body: some View {
        Text("Summary View")
    }
}

1 个答案:

答案 0 :(得分:1)

在 SwiftUI 中,您不能在同一层次结构上有 2 个 .sheet() 修饰符。在这里,第一个 .sheet() 修饰符位于第二个 .sheet() 的父视图之一上。简单的解决方案是移动 .sheets() 之一,使其成为自己的层次结构。

您可以使用 ZStacks:

var body: some View {
    ZStack {
        GeometryReader { g in
            content.frame(width: g.size.width, height: g.size.height)
                .navigationBarTitle("Main", displayMode: .inline)
        }
        
        ZStack{ }
        .sheet(item: $showSheet, content: { mode in
            sheetContent(for: mode)
        })
    }
    .toolbar {
        HStack {
            trailingBarItems
            actionItems
        }
    }
}

或更优雅:

   var body: some View {
        GeometryReader { g in
            content.frame(width: g.size.width, height: g.size.height)
                .navigationBarTitle("Main", displayMode: .inline)
        }
        .background(
            ZStack{ }
            .sheet(item: $showSheet, content: { mode in
                sheetContent(for: mode)
            })
        )
        .toolbar {
            HStack {
                trailingBarItems
                actionItems
            }
        }
    }