swift - 如何让 SwiftUI Picker 在子视图中工作?(变灰)
问题描述
我正在开发一个 SwiftUI 项目,但无法让选择器正常工作。
我将视图层次结构拆分为多个文件,初始视图将所有内容包装在 NavigationView 中。
看起来像这样:
MainFile (TabView -> NavigationView)
- ListPage (NavigationLink)
-- DetailHostPage (Group.EditButton)
if editing
--- DetailViewPage
else
--- DetailEditPage (picker in a form)
我拥有的选择器DetailEditPage
不允许我更改它的值,尽管它确实显示了正确的当前值。
Picker(selection: self.$_myObj.SelectedEnum, label: Text("Type")) {
ForEach(MyEnum.allCases, id: \.self) {
Text("\(String(describing: $0))")
}
}
如果我直接将选择器包装在导航视图中,那么它可以工作,但现在我有一个嵌套导航视图,导致两个后退按钮,这不是我想要的。
是什么导致选择器不允许它的选择改变,我怎样才能让它工作?
编辑
以下是如何复制此内容的示例:
内容视图.swift
class MyObject: ObservableObject {
@Published var enumValue: MyEnum
init(enumValue: MyEnum) {
self.enumValue = enumValue
}
}
enum MyEnum: CaseIterable {
case a, b, c, d
}
struct ContentView: View {
@State private var objectList = [MyObject(enumValue: .a), MyObject(enumValue: .b)]
var body: some View {
NavigationView {
List {
ForEach(0..<objectList.count) { index in
NavigationLink(destination: Subview(myObject: self.$objectList[index])) {
Text("Object \(String(index))")
}
}
}
}
}
}
struct Subview: View {
@Environment(\.editMode) var mode
@Binding var myObject: MyObject
var body: some View {
HStack {
if mode?.wrappedValue == .inactive {
//The picker in this view shows
SubViewShow(myObject: self.$myObject)
} else {
//The picker in this view does not
SubViewEdit(myObject: self.$myObject)
}
}.navigationBarItems(trailing: EditButton())
}
}
struct SubViewShow: View {
@Binding var myObject: MyObject
var body: some View {
Form {
Picker(selection: self.$myObject.enumValue, label: Text("enum values viewing")) {
ForEach(MyEnum.allCases, id: \.self) {
Text("\(String(describing: $0))")
}
}
}
}
}
struct SubViewEdit: View {
@Binding var myObject: MyObject
var body: some View {
Form {
Picker(selection: self.$myObject.enumValue, label: Text("enum values editing")) {
ForEach(MyEnum.allCases, id: \.self) {
Text("\(String(describing: $0))")
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
解决方案
我们不知道您的枚举和模型 (_myObj) 实现。
在下一个片段中是工作代码(复制 - 粘贴 - 测试它),您可以在其中看到如何使用枚举实现选择器。如果您希望在 Form 中使用 Picker,您甚至可以取消注释 Form 声明的行
import SwiftUI
struct Subview: View {
@Binding var flag: Bool
@Binding var sel: Int
var body: some View {
VStack {
Text(String(describing: MyEnum.allCases()[sel]))
Button(action: {
self.flag.toggle()
}) {
Text("toggle")
}
if flag {
FlagOnView()
} else {
FlagOffView(sel: $sel)
}
}
}
}
enum MyEnum {
case a, b, c, d
static func allCases()->[MyEnum] {
[MyEnum.a, MyEnum.b, MyEnum.c, MyEnum.d]
}
}
struct FlagOnView: View {
var body: some View {
Text("flag on")
}
}
struct FlagOffView: View {
@Binding var sel: Int
var body: some View {
//Form {
Picker(selection: $sel, label: Text("select")) {
ForEach(0 ..< MyEnum.allCases().count) { (i) in
Text(String(describing: MyEnum.allCases()[i])).tag(i)
}
}.pickerStyle(WheelPickerStyle())
//}
}
}
struct ContentView: View {
@State var sel: Int = 0
@State var flag = false
var body: some View {
NavigationView {
List {
NavigationLink(destination: Subview(flag: $flag, sel: $sel)) {
Text("push to subview")
}
NavigationLink(destination: Text("S")) {
Text("S")
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
更新更改您的代码
struct SubViewShow: View {
@Binding var myObject: MyObject
@State var sel = Set<Int>()
var body: some View {
Form {
List(selection: $sel) {
ForEach(MyEnum.allCases, id: \.self) {
Text("\(String(describing: $0))")
}.onDelete { (idxs) in
print("delete", idxs)
}
}
Picker(selection: self.$myObject.enumValue, label: Text("enum values viewing")) {
ForEach(MyEnum.allCases, id: \.self) {
Text("\(String(describing: $0))")
}
}.pickerStyle(SegmentedPickerStyle())
}
}
}
struct SubViewEdit: View {
@Binding var myObject: MyObject
@State var sel = Set<Int>()
var body: some View {
Form {
List(selection: $sel) {
ForEach(MyEnum.allCases, id: \.self) {
Text("\(String(describing: $0))")
}.onDelete { (idxs) in
print("delete", idxs)
}
}
Picker(selection: self.$myObject.enumValue, label: Text("enum values editing")) {
ForEach(MyEnum.allCases, id: \.self) {
Text("\(String(describing: $0))")
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
}
看看会发生什么
我想,你只是误解了编辑模式的用途。
推荐阅读
- azure - 使用 Azure B2C 调用 Microsoft 图形 API
- python - 如何在 Azure Blob 中上传大字符串?
- css - 如何将文本右侧的图标与图标列表元素模块对齐?
- ms-word - MS Word Legacy Form Text Form Field 限制编辑,除了更改字体大小
- node.js - 类型错误:期望 `options.agent` 属性为 `http`、`https` 或 `http2`,得到 `options`
- javascript - JavaScript 构造函数的语法糖
- json - MarkLogic 协调数据清洗如何解析数据并分离成
- java - 将数据从片段保存到文件 AndroidStudio
- java - 使用 JavaFX 创建一个带有“wait()”的任务
- json - 从各种类型的 JSON 值流中展开数组