可点击、可移动项目和SwiftUI列表中滚动之间不希望的相互作用



我正在制作一个SwiftUI列表,该列表显示可点击和长按的全宽项目,这些项目是可移动的,并允许详细导航。

我注意到,当列表允许移动项目时,不会检测到.onLongPressGesture,因为列表切换为拖动移动长按的项目。

import SwiftUI
import PlaygroundSupport
struct ContentView: View {
let data = Array(0..<20)
var body: some View {
NavigationStack {
List {
ForEach(data, id:.self) { item in
NavigationLink(destination: EmptyView(), label: {
Rectangle().fill(.mint)
.onTapGesture { print("tapped", item)  }
.onLongPressGesture{ print("longPressed", item)}
})
}.onMove(perform: moveItems)
}
}
}
func moveItems(from source: IndexSet, to destination: Int) { }
}
PlaygroundPage.current.setLiveView(ContentView())

我做了进一步的实验,发现通过simultaneousGesture()使用同时手势可以修复长按时丢失的通知,但却从列表中删除了滚动功能。

import SwiftUI
import PlaygroundSupport
struct ContentViewSimultaneous: View {
let data = Array(0..<20)
var body: some View {
NavigationStack {
List {
ForEach(data, id:.self) { item in
NavigationLink(destination: EmptyView(), label: {
Rectangle().fill(.blue)
.simultaneousGesture(TapGesture().onEnded { print("tapped", item) })
.simultaneousGesture(LongPressGesture().onEnded { _ in
print("longPressed", item) })
})
}.onMove(perform: moveItems)
}
}
}
func moveItems(from source: IndexSet, to destination: Int) { }
}
PlaygroundPage.current.setLiveView(ContentViewSimultaneous())

我现在正在寻找一种方法来实现这一点,如果有任何见解,我将不胜感激!我是SwiftUI的新手,可能会错过一些重要的东西。

我想我能够像您所描述的那样工作。它在iOS 15上没有问题,但在iOS 16中似乎有一个动画错误,导致某些/所有列表行的重排图标没有动画。在编辑模式下拖动项目后,将显示图标。

struct ContentView: View {

@State private var editMode: EditMode = .inactive
@State var disableMove: Bool = true
var body: some View {

let data = Array(0..<20)

NavigationView {
List {
ForEach(data, id:.self) { item in
NavigationLink(destination: EmptyView(), label: {
Rectangle().fill(.mint)
.onTapGesture { print("tapped", item)  }
.onLongPressGesture{ print("longPressed", item)}
})

}
.onMove(perform: disableMove ? nil : moveItems)
}
.toolbar {
ToolbarItem {

Button {
withAnimation {
self.disableMove.toggle()
}
} label: {
Text(editMode == .active ? "Done" : "Edit")
}

}
}
.environment(.editMode, $editMode)

}
.onChange(of: disableMove) { disableMove in
withAnimation {
self.editMode = disableMove ? .inactive : .active

}
}
.navigationViewStyle(.stack)

}

func moveItems(from source: IndexSet, to destination: Int) { }

}

不确定这是否有助于

enum Status {
case notPressed
case pressed
case longPressed
}
struct ContentView: View {
@State private var status = Status.notPressed

var body: some View {
Rectangle()
.foregroundColor(color)
.simultaneousGesture(LongPressGesture().onEnded { _ in
print("longPressed")
status = .longPressed
})
.simultaneousGesture(TapGesture().onEnded { _ in
print("pressed")
status = .pressed
})
}

var color: Color {
switch status {
case .notPressed:
return .mint
case .pressed:
return .yellow
case .longPressed:
return .orange
}
}
}

最新更新