简体   繁体   English

如何在 SwiftUI 中显示来自多个枚举选择器选择的详细信息屏幕

[英]How to display details screens from multiple enum picker selections in SwiftUI

I am using swiftui to update an app which can display a detail screen based on the users picker selection.我正在使用 swiftui 来更新可以根据用户选择器选择显示详细信息屏幕的应用程序。 I created a view for each detail screen(about 50) and I have a multi-picker for the user to select which detail screen to display.我为每个详细信息屏幕(大约 50 个)创建了一个视图,并且我有一个多选择器供用户选择 select 要显示的详细信息屏幕。 What is the best way to use the selections from the picker to show the appropriate detail view.使用选择器中的选择来显示适当的详细视图的最佳方式是什么。

Here is an simplified example of the multi-picker:这是多选择器的简化示例:

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

        }
    }
}

there various ways to do this, here is a simple approach: (note I had to modify the Pickers)有多种方法可以做到这一点,这是一个简单的方法:(注意我必须修改 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)")
    }
}

Does this one helps, here we are using a switch statement and return a view (or a NavigationLink ) depending on the context这有帮助吗,这里我们使用switch语句并根据上下文返回view (或NavigationLink

switch (selectedHypoHyper, selectedLyte, selectedDetail) {
case (.Hyper, .Na, .Causes): EmptyView()
case (.Hyper, .Na, .Signs): EmptyView()
case (.Hyper, .K, .Causes): EmptyView()
case (.Hyper, .K, .Signs): EmptyView()
// Continue with other cases ...
default: EmptyView()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM