You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI Drag&Drop:如何在validateDrop方法中获取被拖拽对象

问题核心原因

validateDrop 方法要求同步返回布尔类型的校验结果,你调用的 itemProvider.loadObject(ofClass:) 是异步加载接口,加载回调执行时,validateDrop 已经提前返回了结果,所以无法在回调里拿到对象做即时校验。

最优解决方案:使用拖拽本地对象实现同步读取

同App进程内的拖拽场景,可以在构造拖拽项时将对象注册为NSItemProvider的本地对象,在validateDrop中直接同步读取,不需要走异步加载流程:

  1. 首先修改拖拽侧的代码,注册本地对象:
// 你定义Drag的位置代码示例
.onDrag {
    let playerInstance = // 你的被拖拽Player对象
    let provider = NSItemProvider(object: playerInstance)
    // 注册本地对象,同进程内可直接同步读取
    provider.registerObject(playerInstance, visibility: .all)
    return provider
}
  1. 调整validateDrop的代码,直接同步读取对象做校验:
func validateDrop(info: DropInfo) -> Bool {
    print("Drop Validating")
    print ("Dropping into slot where  \(rosterPlayer!.givenName!) \(rosterPlayer!.surname!) is")

    guard info.hasItemsConforming(to: [PlayerShirtUTT.uti.identifier]),
          let itemProvider = info.itemProviders(for: [PlayerShirtUTT.uti.identifier]).first,
          // 直接同步取本地对象,无需等待异步回调
          let dragPlayer = itemProvider.localObject as? Player else {
        return false
    }
    // 这里直接做你的校验逻辑
    print("拿到拖拽的Player对象:\(dragPlayer.givenName ?? "")")
    // 返回你的实际校验结果
    return true
}
跨进程拖拽场景的替代方案

如果你的拖拽需要支持跨App场景,本地对象无法生效,可以调整校验逻辑:

  • validateDrop阶段只校验UTI类型是否符合,先返回true
  • 所有业务逻辑校验放在performDrop方法中执行,如果校验不通过直接返回false,系统会自动判定为drop失败,不会执行后续操作

内容的提问来源于stack exchange,提问作者Andy Davison

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 18:06:00