当 editMode 处于活动状态时,选择器不工作

Picker not working when editMode is active

我有一个视图 (Form),基本上,它有一个选择器和一个可以由用户重新排列的项目列表。我希望列表始终是可编辑的,这样用户就不必点击 Edit 按钮(我觉得 Edit 只影响表单一小部分的按钮。

我通过设置环境变量 editMode 成功实现了上述始终在线编辑:.environment(\.editMode, .constant(.active)).

问题是,当表单可编辑时,选择器停止工作(即,当您点击它时,它不会切换到选项列表)。

这是重现我的问题的 MCVE:

import SwiftUI

struct SampleView: View {
  enum SortBy: String, CaseIterable {
    case FirstName
    case LastName

    var name: String {
      switch (self) {
      case .FirstName:
        return "First name"
      case .LastName:
        return "Last name"
      }
    }
  }
  @State var sortBy = SortBy.FirstName

  var body: some View {
    Form {
      Section(header: Text("General")) {
        Picker("Sort by", selection: $sortBy) {
          ForEach(SortBy.allCases, id: \.self) { sortBy in
            Text(sortBy.name).tag(sortBy)
          }
        }
      }

      Section(header: Text("Phone order")) {
        ForEach(1..<10) { number in
          Text("\(number)")
        }
        .onMove(perform: onMove)
        .padding(.leading, -39) // remove space dedicated to delete button
      }
    }
    .environment(\.editMode, .constant(.active)) // <--
    .navigationBarTitle(Text("Sample View"))
  }

  private func onMove(source: IndexSet, destination: Int) {
    // ...
  }
}

struct SampleView_Previews: PreviewProvider {
  static var previews: some View {
    NavigationView {
      SampleView()
    }
  }
}

显然我可以食言并恢复编辑按钮,但我想知道是否有任何方法可以使列表保持可编辑状态并让选择器正常工作。

我已经看过this other question,但没有解决问题。

我了解到问题与编辑时导航链接被禁用有关。

由于 editMode 是表单的 属性,我尝试的一个选项是创建一个具有两个单独表单的 VStack,因此只有列表中的那个是可编辑的.问题是我无法获得正确的布局,更不用说我以两个可滚动区域结束了。

另一个想法是使用 onTapGesture 手动导航到选择器的列表,但我还没有找到使用 SwiftUI 的方法。

到目前为止,我唯一的解决办法是将选择器的样式更改为 SegmentedPickerStyle,但是当排序选项(枚举)增长时,它不会很有用。

目前看来这样的组合是不可能的...在下面找到替代解决方案的建议变体 - 这个想法是使用 in-section-only 按钮来激活重新排序

    @State private var reorderMode: EditMode = .inactive
    var body: some View {
        Form {
            Section(header: Text("General")) {
                Picker("Sort by", selection: $sortBy) {
                    ForEach(SortBy.allCases, id: \.self) { sortBy in
                        Text(sortBy.name).tag(sortBy)
                    }
                }
            }

            Section(header:
                HStack {
                    Text("Phone order")
                    Spacer()
                    Button(self.reorderMode == .inactive ? "Reorder" : "Done") {
                        self.reorderMode = self.reorderMode == .active ? .inactive : .active
                    }
                }
            ) {
                ForEach(1..<10) { number in
                    Text("\(number)")
                }
                .onMove(perform: onMove)
                    .padding(.leading, self.reorderMode == .active ? -39 : 0) // remove space dedicated to delete button
            }
        }
        .environment(\.editMode, $reorderMode)
        .navigationBarTitle(Text("Sample View"))
    }