swift - 如何在 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( )
}
}
}
}
解决方案
有多种方法可以做到这一点,这是一个简单的方法:(注意我必须修改 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)")
}
}
推荐阅读
- react-native - 从底部单击时如何使抽屉从右侧滑动
- javascript - Metro builder 不关注 index.js
- mongodb - 如何在 Macbook(不是 M1)上安装 mongo db
- azure - 如何使用 Azure CLI 命令清除 Cosmos (MongoAPI) 集合?
- javascript - 如何一次查询多个 MongoDB 集合?
- php - 在 Symfony 5 中只删除一个会话
- php - Pusher api 没有监听 laravel 事件
- matplotlib - 如何在 x 轴刻度的末尾放置一些空格
- javascript - Javascript - 如何使用正则表达式提取文本
- flutter - 未处理的异常:在 null 上调用了 getter 'name'