swiftui - 在编辑模式下正常的点击和滑动操作?

标签 swiftui swiftui-list swiftui-navigationview

我正在开发一个应用程序,其中一个 View 的主要目标是允许用户重新排序导航链接列表,但我还希望允许导航和其他一些操作。我希望用户能够:

  1. 通过拖动重新排序控件来重新排序。
  2. 通过点按该行中的其他位置导航到该链接。
  3. 从前缘滑动即可激活滑动操作。

目前,启用 EditMode(以允许重新排序)会禁用导航和滑动操作;我一直无法找到同时允许所有 3 个功能的解决方法。有什么好的办法吗?

这是一个例子:

struct ReorderableListView: View {
    var items: [X] // List of custom objects
    var body: some View {
       NavigationView {
           List {
               ForEach(items) { item in
                   NavigationLink(destination: CustomView(item)) { // winds up disabled by edit mode
                      Text(item.name)
                   }
                   .swipeActions(edge: .leading) { Button("Swipe") {print("swipe")} } // winds up disabled by edit mode
               }
               .onMove { from, to in
                   print("move \(from)  to \(to)")
               }
           }
           .environment(\.editMode, .constant(.active)) // always in edit mode for reordering
       }
    }
}

更新:

根据已接受的答案,这种行为似乎在 iOS 16 中得到了更新:现在,如果实现了 onMove,即使不在编辑模式下,您也可以通过长按重新排序,这允许这三种 Action 要并存。我添加了自定义拖动 handle ,以使这种行为对用户来说显而易见,但除此之外,我将采用下面接受的答案中给出的解决方案。

最佳答案

我不确定在这种情况下 .environment 是否必要(我可能是错的)。您可以删除该部分。

此外,您应该为 foreach 中的每个项目添加一个 ID。理想情况下,当您创建新项目时,这应该来自您的模型(例如,您的模型可以包含 ID 变量 = UUID()),但目前我们可以将其内联添加到您的 foreach 中。

我必须在最后编写一些代码才能启动并运行它,因此我的解决方案基于我编写的代码(与您的非常相似,但缺少您的自定义项目对象):

    struct ReorderableListView: View {
    var items: [X] // List of custom objects
    var body: some View {
       NavigationView {
           List {
                    // added ID here
               ForEach(items, id: \.self) { item in
                   NavigationLink(destination: CustomView(item)) { // winds up disabled by edit mode
                      Text(item.name)
                   }
                   .swipeActions(edge: .leading) { Button("Swipe") {print("swipe")} } // winds up disabled by edit mode
               }
               .onMove { from, to in
                   print("move \(from)  to \(to)")
               }
           }
          // REMOVED .environment(\.editMode, .constant(.active)) // always in edit mode for reordering
       }
    }
}

作为引用,这里是我在本地编写的代码,以填补空白。这就是我在您的代码中实现的有效方法:

    struct ReorderableListView: View {
    @State var items = [1, 2, 3] // List of custom objects
    var body: some View {
        NavigationView {
            List {
                ForEach(items, id: \.self) { item in
                    NavigationLink(destination: ContentView2()) { // winds up disabled by edit mode
                        Text("\(item)")
                    }
                    .swipeActions(edge: .leading) { Button("Swipe") {print("swipe")} } // winds up disabled by edit mode
                }
                .onMove { from, to in
                    print("move \(from)  to \(to)")
                }
            }
         //   .environment(\.editMode, .constant(.active)) // always in edit mode for reordering
        }
    }
}

关于swiftui - 在编辑模式下正常的点击和滑动操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73889241/

相关文章:

ios - SwiftUI在FetchRequest中使用带有结构参数的关系谓词

swiftui - 更改 iOS15 中列表的背景颜色

SwiftUI macOS 在 TextField 处于事件状态时使用箭头键滚动列表

SwiftUI - NavigationLink 不适用于按钮

swiftui - Apple 提供的环境变量 `dismissSearch` 不起作用

ios - 如何使用 SwiftUI 中的按钮在 View 之间导航?

swiftui - 在 SwiftUI 的 SplitView 中导航到 master 内部而不是 detail

SwiftUI 导航多个后退按钮

ios - SwiftUI - 使用 Toggle 隐藏列表项

macos - SwiftUI macOS 工具栏图标对齐三栏布局