如何在 SwiftUI 中进行拖放

问题描述 投票:0回答:1

我目前收到以下错误:

Instance method 'loadObject(ofClass:completionHandler:)' requires that 'NSItemProvider' conform to '_ObjectiveCBridgeable'

使用此代码:

.onDrop(of: ["public.text"], isTargeted: nil) { providers, location in
     guard let provider = providers.first else { return false }
             
     provider.loadObject(ofClass: NSItemProvider.self) { item, error in
          guard error == nil, let item = item else { return }
                  
          if let curTool = item as? Tools, let dropURL = item as? URL {
                handleDrop(with: (curTool, dropURL))
          }
     }
     return true
}


func handleDrop(with dropData: (Tools, URL)) {
     let (curTool, curURL) = dropData
}

这是拖动时的匹配(curTool 是一个简单的枚举):

.onDrag {
    let curTool = Tools.circle
    let curURL = URL(string: "https://example.com")!
                    
    let itemProvider = NSItemProvider(object: NSString(string: "Dummy data"))
    itemProvider.registerObject(String(describing: curTool) as NSItemProviderWriting, visibility: .all)
    itemProvider.registerObject(curURL as NSItemProviderWriting, visibility: .all)
    return itemProvider
}
swift macos user-interface swiftui
1个回答
0
投票

您使用的

loadObject
方法是错误的 - 作为
ofClass
参数,您需要传递要使用
NSItemProvider
加载的类型,而不是
NSItemProvider
本身:

provider.loadObject(ofClass: Tools.self) { item, error in
    guard error == nil, let item = item else { return }
              
    [...]
}

但是,上述也意味着您必须使您的工具类型符合

NSItemProviderReading
。据我所知,您还没有这样做,而是将其转换为
String
,所以在您当前的代码形式中它将是:

provider.loadObject(ofClass: String.self) { item, error in
    guard error == nil, let item = item else { return }
           
    [convert `item` (a String) back to the Tools custom type you have...]
}

此外,您无法在单个 loadObject 调用中加载这两种表示形式,您需要为 URL 创建另一个表示形式并以类似方式处理结果:

.onDrop(of: ["public.text"], isTargeted: nil) { providers, location in
     guard let provider = providers.first else { return false }
             
     provider.loadObject(ofClass: String.self) { item, error in
        guard error == nil, let item = item else { return }
                  
        [...]
     }

     provider.loadObject(ofClass: URL.self) { item, error in
         guard error == nil, let item = item else { return }
                  
         [...]
     }

     return true
}

补充说明

如果您的操作系统支持允许,请查看新的

Transferable
协议及其通过
draggable()
dropDestination()
的拖放支持。

© www.soinside.com 2019 - 2024. All rights reserved.