【问题标题】:How to display details screens from multiple enum picker selections in SwiftUI如何在 SwiftUI 中显示来自多个枚举选择器选择的详细信息屏幕
【发布时间】:2021-08-28 21:11:21
【问题描述】:

我正在使用 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( )
            }

        }
    }
}

【问题讨论】:

    标签: swift swiftui picker


    【解决方案1】:

    有多种方法可以做到这一点,这是一个简单的方法: (注意我必须修改 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)")
        }
    }
    

    【讨论】:

    • 感谢您的回答。它非常接近我想要的,但我想要实现的是切换“HyperNaCauses”、“HypoNaCauses”等 50 个视图。想知道是否有一种有效的方法来写出这个开关?
    【解决方案2】:

    这个有帮助吗,这里我们使用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()
    }
    

    【讨论】:

    • 谢谢。这确实有帮助并使代码易于阅读。只是我有 50 个案例陈述,我很好奇是否有人有更简洁的方式来显示子视图。
    猜你喜欢
    • 2018-12-08
    • 2016-03-24
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多