blog
blog copied to clipboard
How to add drag and drop in SwiftUI
In some case, we should not use base type like UTType.text
but to be more specific like UTType.utf8PlainText
import UniformTypeIdentifiers
var dropTypes: [UTType] {
[
.fileURL,
.url,
.utf8PlainText,
.text
]
}
func handleDrop(info: DropInfo) -> Bool {
for provider in info.itemProviders(for: dropTypes) {
for type in dropTypes {
provider.loadDataRepresentation(forTypeIdentifier: type.identifier) { data, _ in
guard
let data = data,
let string = String(data: data, encoding: .utf8)
else { return }
DispatchQueue.main.async {
let item =Item(text: string)
withAnimation {
self.stack.items.append(item)
}
}
}
}
return true
}
return true
}
Handle image drop
func handleDrop(_ info: DropInfo) -> Bool {
if let provider = info.itemProviders(for: [.fileURL]).first {
provider.loadDataRepresentation(
forTypeIdentifier: UTType.fileURL.identifier,
completionHandler: { data, error in
if let data = data,
let string = String(data: data, encoding: .utf8),
let url = URL(string: string),
url.isImageFile,
let image = NSImage(contentsOf: url) {
DispatchQueue.main.async {
self.image = image
}
}
}
)
return true
}
return false
}
struct SelectFileView: View {
@State var isDrop: Bool = false
var body: some View {
VStack(alignment: .leading) {
...
}
.border(isDrop ? R.color.separator : Color.clear)
.onDrop(of: [.fileURL], delegate: self)
}
}
extension SelectFileView: DropDelegate {
func dropEntered(info: DropInfo) {
self.isDrop = true
}
func dropExited(info: DropInfo) {
self.isDrop = false
}
func performDrop(info: DropInfo) -> Bool {
handleDrop(info)
}
}
Read more
- https://stackoverflow.com/questions/69324953/swiftui-not-getting-dropped-nsstring-value-in-dropdelegate/69325742#69325742
on SwiftUI + Appkit project running on Xcode 12.0 beta 2 (12A6163b), dropEntered(info:)
not trigger but func dropExited(info: DropInfo)
does, very strange.
@onmyway133 Hi, I used your code to post a SO here, https://stackoverflow.com/questions/62806067/on-swiftui-appkit-project-dropentered-of-dropdelegate-not-trigged. Please let me know if you don't like it. Thank you.