简体   繁体   English

SwiftUI - 由于 DragGesture,List 中的 .onDelete 功能丢失

[英]SwiftUI - Loss of .onDelete Functionality in List as a result of DragGesture

The DragGesture() causes loss of functionality of the.onDelete function inside of the list. DragGesture() 导致列表内的.onDelete function 功能丢失。 I made a basic example of the interaction:我做了一个交互的基本例子:


class MenuViewModel: ObservableObject {
  @Published var dragEnabled: Bool = true
}

struct RootView: View {
  @StateObject var viewModel = MenuViewModel()

  var body: some View {
    ZStack {
      NavView()
    }
    .environmentObject(viewModel)
    // Can be diabled on ChildView, but will need to be re-enabled on RootView
    .gesture(DragGesture()
      .onChanged { _ in
        guard viewModel.dragEnabled else { return }
        print("Drag Gesture Active")
      })
  }
}

struct NavView: View {
  var body: some View {
    NavigationView {
      NavigationLink {
        ChildView()
      } label: {
        Text("Go to ChildView")
      }
      Text("Drag Gesture needs to be enabled")
    }
    .navigationViewStyle(.stack)
  }
}

struct ChildView: View {
  @EnvironmentObject var viewModel: MenuViewModel
  @State var list = ["1", "2", "3"]

  var body: some View {
    List {
      ForEach(list, id: \.self) { item in
        Text(item)
      }
      .onDelete { indexSet in
        print("OnDelete Works!")
        list.remove(atOffsets: indexSet)
      }
      .navigationTitle("OnDelete Enabled")
    }
    .onAppear {
      viewModel.dragEnabled = false
      print("Drag Gesture Disabled")
    }
    .onDisappear {
      viewModel.dragEnabled = true
      print("Drag Gesture Enabled")
    }
  }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        RootView()
    }
}

Attempted to use:尝试使用:

  • .simultaneously(with: .同时(与:
  • .highPriorityGesture( .highPriorityGesture(
  • .allowsHitTesting(false) .allowsHitTesting(假)
  • changing location of gesture modifier更改手势修改器的位置
  • creating custom gesture for swipe为滑动创建自定义手势
  • disabling gesture if on specific screen (causes rootView to refresh)如果在特定屏幕上禁用手势(导致 rootView 刷新)
  • Using ObservedObjects to pass value between views使用 ObservedObjects 在视图之间传递值
  • Using EnvironmentObject to pass value into environment使用 EnvironmentObject 将值传递给环境
  • Using Environment value to pass value into environment使用环境价值将价值传递给环境
  • .onReceive/.onAppear/.onDisappear/.onChange .onReceive/.onAppear/.onDisappear/.onChange

Nothing is working as expected.一切都没有按预期工作。 Any suggestions would be appreciated.任何建议,将不胜感激。 I know in this example the DragGesture does not do anything.我知道在这个例子中 DragGesture 没有做任何事情。 I am using the DragGesture in my app so users can drag a side menu into view.我在我的应用程序中使用 DragGesture,因此用户可以将侧边菜单拖动到视图中。

You can use GestureMask to enable/disable parent or child gestures.您可以使用GestureMask启用/禁用父或子手势。 Do this in RootView :RootView中执行此操作:

  var body: some View {
    ZStack {
      NavView()
    }
    .environmentObject(viewModel)
    // Can be diabled on ChildView, but will need to be re-enabled on RootView
    .gesture(DragGesture()
      .onChanged { _ in
        guard viewModel.dragEnabled else { return }
        print("Drag Gesture Active")
      }, including: viewModel.dragEnabled ? .gesture : .subviews) // here
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM