Как заставить работать SwiftUI Picker в subview? (Серый) - PullRequest
0 голосов
/ 08 марта 2020

Я работаю над проектом 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))")
    }
}

Если я обертываю средство выбора в виде навигации напрямую, то оно работает, но теперь у меня есть вложенное представление навигации, в результате чего появляются две кнопки «назад», а это не то, что мне нужно.

Что вызывает средство выбора, чтобы не допустить изменения его выделения, и как я могу заставить его работать?

РЕДАКТИРОВАТЬ

Вот пример того, как повторить это:

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

1 Ответ

0 голосов
/ 09 марта 2020

Мы не имеем представления о реализации enum и модели (_myObj).

В следующем фрагменте кода работает код (копировать - вставить - протестировать его), где вы можете увидеть, как реализовать средство выбора с ENUM. Вы даже можете раскомментировать строки, в которых объявлена ​​Форма, если вы хотите, чтобы ваш Пикер в Форме

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

и увидел, что происходит

Я думаю, вы просто неправильно поняли, для чего нужен режим редактирования.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...