首页 > 解决方案 > 如何在 SwiftUI 中显示来自多个枚举选择器选择的详细信息屏幕

问题描述

我正在使用 swiftui 更新可以根据用户选择器选择显示详细信息屏幕的应用程序。我为每个详细信息屏幕(大约 50 个)创建了一个视图,并且我有一个多选择器供用户选择要显示的详细信息屏幕。使用选择器中的选择来显示适当的详细视图的最佳方式是什么。

这是多选择器的简化示例:

struct PickerMenu: View {

    enum HypoHyper: String, CaseIterable, Identifiable {
        case Hypo
        case Hyper

        var id: String { self.rawValue }
    }

    enum Lytes: String, CaseIterable, Identifiable {
        case Na
        case K

        var id: String { self.rawValue }
    }

    enum Details: String, CaseIterable, Identifiable {
        case Causes
        case Signs

        var id: String { self.rawValue }
    }


    @State var selectedHypoHyper = HypoHyper.Hyper
    @State var selectedLyte = Lytes.Na
    @State var selectedDetail = Details.Causes


    var body: some View {
        GeometryReader { geometry in
            HStack {
                Picker(selection: self.$selectedHypoHyper, label: Text("")) {
                    ForEach(HypoHyper.allCases) { hypoHyper in
                        Text(hypoHyper.rawValue).tag(hypoHyper.rawValue)
                    }
                }
                .frame(width: geometry.size.width/3, height: 150, alignment: .center)
                .clipped( )
                Picker(selection: self.$selectedLyte, label: Text("")) {
                    ForEach(Lytes.allCases) { lyte in
                        Text(lyte.rawValue).tag(lyte.rawValue)
                    }
                }
                .frame(width: geometry.size.width/3, height: 150, alignment: .center)
                .clipped( )
                Picker(selection: self.$selectedDetail, label: Text("")) {
                    ForEach(Details.allCases) { detail in
                        Text(detail.rawValue).tag(detail.rawValue)
                    }
                }
                .frame(width: geometry.size.width/3, height: 150, alignment: .center)
                .clipped( )
            }

        }
    }
}

标签: swiftswiftuipicker

解决方案


有多种方法可以做到这一点,这是一个简单的方法:(注意我必须修改 Pickers)

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            PickerMenu()
        }.navigationViewStyle(StackNavigationViewStyle())
    }
}

// put these outside the PickerMenu for other views to use
enum HypoHyper: String, CaseIterable, Identifiable {
    case Hypo
    case Hyper
    var id: String { self.rawValue }
}

enum Lytes: String, CaseIterable, Identifiable {
    case Na
    case K
    var id: String { self.rawValue }
}

enum Details: String, CaseIterable, Identifiable {
    case Causes
    case Signs
    var id: String { self.rawValue }
}

struct PickerMenu: View {
    
    @State var selectedHypoHyper: HypoHyper = HypoHyper.Hyper
    @State var selectedLyte = Lytes.Na
    @State var selectedDetail = Details.Causes
    @State var showDetailView = false
    
    var body: some View {
        VStack (spacing: 30) {
            GeometryReader { geometry in
                HStack {
                    Picker("", selection: $selectedHypoHyper) {
                        ForEach(HypoHyper.allCases, id: \.id) { hypoHyper in
                            Text(hypoHyper.rawValue).tag(hypoHyper)
                        }
                    }
                    .frame(width: geometry.size.width/3, height: 150, alignment: .center)
                    .clipped( )
                    Picker("", selection: $selectedLyte) {
                        ForEach(Lytes.allCases, id: \.id) { lyte in
                            Text(lyte.rawValue).tag(lyte)
                        }
                    }
                    .frame(width: geometry.size.width/3, height: 150, alignment: .center)
                    .clipped( )
                    Picker("", selection: $selectedDetail) {
                        ForEach(Details.allCases, id: \.id) { detail in
                            Text(detail.rawValue).tag(detail)
                        }
                    }
                    .frame(width: geometry.size.width/3, height: 150, alignment: .center)
                    .clipped( )
                }
            }
            
            Button("Show Detail View") {
                showDetailView = true
            }
            
            NavigationLink("", destination: SomeDetailView(
                selectedHypoHyper: $selectedHypoHyper,
                selectedLyte: $selectedLyte,
                selectedDetail: $selectedDetail), isActive: $showDetailView)
        }
    }
}

struct SomeDetailView: View {
    @Binding var selectedHypoHyper: HypoHyper
    @Binding var selectedLyte: Lytes
    @Binding var selectedDetail: Details
    
    var body: some View {
        // here determine which view you want to show based on the selections, eg a switch(...) {..}
        Text("selectedHypoHyper: \(selectedHypoHyper.rawValue)")
        Text("selectedLyte: \(selectedLyte.rawValue)")
        Text("selectedDetail: \(selectedDetail.rawValue)")
    }
}

推荐阅读