SwiftUI 3在Mac端如何限制可接收的拖放对象类型?
问题根因
这不是实现错误,也不是SwiftUI接口bug,是macOS系统拖放本地文件的默认行为:所有本地文件的拖放事件,在onDrop类型匹配阶段只会携带UTType.fileURL标识,系统不会在拖放预校验阶段解析文件对应的实际UTType,所以直接传入.applicationBundle/.pdf这类文件类型参数无法触发匹配。
解决方案
需要先接收UTType.fileURL类型,再在拖放回调中校验文件实际类型:
- 首先确保导入
UniformTypeIdentifiers框架 - 将
onDrop的接收类型设置为[.fileURL] - 在回调中读取拖入的文件URL,校验URL对应的UTType是否符合要求
修改后的参考代码如下:
import UniformTypeIdentifiers import SwiftUI List(appsToIgnore, id: \.self, selection: $selection) { Text($0) } .onDrop(of: [.fileURL], isTargeted: $isTargeted) { providers in for provider in providers { provider.loadObject(ofClass: NSURL.self) { url, error in guard let url = url as? URL, error == nil else { return } do { let resourceValues = try url.resourceValues(forKeys: [.typeIdentifierKey]) guard let fileUTType = resourceValues.typeIdentifier.flatMap(UTType.init), // 此处可添加多个需要匹配的类型判断,比如同时校验application、pdf等 fileUTType.conforms(to: .applicationBundle) else { // 类型不匹配直接忽略 return } // 类型校验通过,执行后续业务逻辑 print("符合要求的应用包拖入成功:\(url.path)") } catch { print("读取文件类型失败:\(error)") } } } return true }
补充优化(可选)
如果需要在拖放悬停阶段就给出是否允许放置的视觉反馈,可以自定义DropDelegate,在validateDrop方法中提前完成类型校验,根据校验结果返回对应放置状态即可。
内容的提问来源于stack exchange,提问作者godbout
相关产品推荐
相关产品推荐

