macOS13.2、Xcode14.2下SwiftUI dropDestination处理URL输出重复,是Bug吗?
SwiftUI dropDestination 重复打印URL文件名:正常行为还是Bug?
问题背景
在 macOS 13.2、Xcode 14.2 环境下,编写如下SwiftUI代码实现文件拖拽功能:
struct ContentView: View { var body: some View { Text("Drop files over here!").font(.largeTitle) .frame(maxWidth: .infinity, maxHeight: .infinity) .dropDestination(for: URL.self) { urls, _ in for u in urls { print(u.lastPathComponent) } return true } } }
运行后发现打印出的URL文件名存在重复情况,请问这属于正常行为还是Bug?
解答
这是正常行为,并非Bug。
dropDestination的处理闭包会被系统多次触发:当拖拽的文件进入目标区域、悬停在区域内、以及最终完成放下动作时,系统都会调用这个闭包。如果只是简单打印URL,自然会看到重复的输出。
解决办法
如果需要避免重复处理或重复打印,可以通过以下方式优化:
- 维护一个已处理URL的集合,过滤掉已经处理过的文件
- 通过
DropSession的状态判断,仅在完成拖拽放下动作时执行处理逻辑
示例代码(已处理集合过滤):
struct ContentView: View { // 存储已处理的URL,避免重复输出 @State private var processedURLs: Set<URL> = [] var body: some View { Text("Drop files over here!").font(.largeTitle) .frame(maxWidth: .infinity, maxHeight: .infinity) .dropDestination(for: URL.self) { urls, dropSession in // 筛选出未处理的URL let unprocessedURLs = urls.filter { !processedURLs.contains($0) } for u in unprocessedURLs { print(u.lastPathComponent) processedURLs.insert(u) } // 拖拽完成后清空集合,以便下次拖拽重新处理 if dropSession.progress.isFinished { processedURLs.removeAll() } return true } } }
内容的提问来源于stack exchange,提问作者Somebody
相关产品推荐
相关产品推荐

