来自https://github.com/onmyway133/blog/issues/594的代码,并进行一些更改。
很简单,创建一个 SwiftUI + Appkit
项目,将下面的代码复制粘贴到项目中。
import SwiftUI
struct SelectFileView: View {
let buttonTitle: String
@State var isDrop: Bool = false
var body: some View {
VStack(alignment: .leading) {
Button(action: {}) {
Text(buttonTitle)
}
.offset(x: -16)
Text("Alternatively, you can drag and drop file here")
.font(.footnote)
.foregroundColor(Color.gray)
}
.border(isDrop ? Color.orange : Color.clear)
.onDrop(of: ["public.image"], delegate: self)
.padding(32)
}
}
extension SelectFileView: DropDelegate {
func dropEntered(info: DropInfo) {
print("dropEntered")
self.isDrop = true
}
func dropExited(info: DropInfo) {
print("dropExited")
self.isDrop = false
}
func performDrop(info: DropInfo) -> Bool {
guard
let itemProvider = info.itemProviders(for: ["public.image"]).first
else { return false }
itemProvider.loadItem(forTypeIdentifier: "public.image", options: nil) { item, error in
guard
let data = item as? Data,
let url = URL(dataRepresentation: data, relativeTo: nil)
else { return }
}
return true
}
}
struct ContentView: View {
var body: some View {
SelectFileView(buttonTitle: "Drop Test")
}
}
在 Xcode 12.0 beta 2 上构建并运行后(12A6163b)
,它总是 print dropExited
,这就是问题所在。
dropEntered(info:)
未触发,但dropExited(info:)
有效