SwiftUI拖放实现中performDrop后onDrag被自动重复调用的问题求助
SwiftUI拖放实现中performDrop后onDrag被自动重复调用的问题求助
我在SwiftUI的VStack中实现列表项的拖放重排序功能时,碰到了一个诡异的问题:每当完成一次拖放操作(performDrop方法执行完毕后),被拖拽的那个列表项的onDrag闭包会被自动触发一次,可我明明已经松开了拖拽手势,完全没有再次触发拖拽的操作。
先贴我的DropDelegate实现代码:
private struct StandardDropDelegate: DropDelegate { let destinationItem: StandardReorderedListItem @Binding var sourceContent: [StandardReorderedListItem] @Binding var draggedItem: StandardReorderedListItem? func dropUpdated(info: DropInfo) -> DropProposal? { return DropProposal(operation: .move) } func performDrop(info: DropInfo) -> Bool { print("dropped item: \(String(describing: draggedItem))\n===========================") self.draggedItem = nil return true } func dropEntered(info: DropInfo) { guard let draggedItem, let fromIndex = sourceContent.firstIndex(of: draggedItem), let toIndex = sourceContent.firstIndex(of: destinationItem), fromIndex != toIndex else { return } withAnimation(.easeInOut) { self.sourceContent.move(fromOffsets: IndexSet(integer: fromIndex), toOffset: (toIndex > fromIndex ? (toIndex + 1) : toIndex)) } } }
然后是列表视图的实现代码:
public struct StandardReorderedListView: View { @Binding private var content: [StandardReorderedListItem] @State private var draggedItem: StandardReorderedListItem? private let type: ReorderedListType = .standard public init(_ content: Binding<[StandardReorderedListItem]>) { self._content = content } @ViewBuilder public var body: some View { ScrollView(.vertical) { VStack { ForEach(content) { item in ReorderedListItemView(state: .constant(.active), // Don't care isDragging: Binding(get: { self.draggedItem?.id == item.id }, set: { _ in }), label: item.label, itemType: type, icon: item.icon, action: item.action) .onDrag { print("drag item: \(item)\n===========================") self.draggedItem = item return NSItemProvider(object: item.id.uuidString as NSString ) } .onDrop(of: [.text], delegate: StandardDropDelegate(destinationItem: item, sourceContent: $content, draggedItem: $draggedItem)) } } } } }
下面是控制台的输出日志,能清晰看到每次performDrop执行后,onDrag会被莫名触发一次:
drag item: StandardReorderedListItem(id: 3BDFE0B4-58DF-42C0-8FAB-109D3BFD191E, label: "Item 1", icon: Optional(SwiftUI.Image(provider: SwiftUI.ImageProviderBox<SwiftUI.Image.NamedImageProvider>)), action: Optional((Function))) =========================== dropped item: Optional(StandardReorderedListItem(id: 3BDFE0B4-58DF-42C0-8FAB-109D3BFD191E, label: "Item 1", icon: Optional(SwiftUI.Image(provider: SwiftUI.ImageProviderBox<SwiftUI.Image.NamedImageProvider>)), action: Optional((Function)))) =========================== drag item: StandardReorderedListItem(id: 3BDFE0B4-58DF-42C0-8FAB-109D3BFD191E, label: "Item 1", icon: Optional(SwiftUI.Image(provider: SwiftUI.ImageProviderBox<SwiftUI.Image.NamedImageProvider>)), action: Optional((Function))) ===========================
补充说明:因为需要兼容iOS 15及以上版本,所以我没法用新的Transferable API,只能用这种传统的拖放实现方式。有没有大佬能帮我分析下问题出在哪,以及怎么解决这个自动触发onDrag的问题?感谢!
内容来源于stack exchange
相关产品推荐
相关产品推荐

