I've put together a simplified code example to test how the location
of dropDestination
works within a Grid
View. When I attach dropDestination
to Grid
, GridRow
or the Text("\(row) , \(column)")
view, I get a CGPoint
corresponding to the drop location within the views coordinate space. But the problem is how would I get the either the index of a grid cell eg. (1, 1) or the grid cell view itself?
Apple's documentation regarding drag and drop in SwiftUI says to
prefer using transferable items
which I interpret as them recommending dropDestination
over the older onDrop
with an NSItemProvider
.
But unlike in a List
view there doesn't seem to be away for location
to return discrete values. If I instead attach dropDestination
to a one of the nested ForEach
loops within the Grid
view, the drop gesture doesn't do anything?
Also dropDestination
exhibits some default behaviour that I don't want.
- When dragging a view a little plus symbol within a green circle appears
- Views can be dragged and dropped out of the apps window which transfers the data, in this case it creates a text file in the desktop
I could of sworn I read documentation or online resources that implied this behaviour was supposed to be opt-in rather than applied by default?
Ultimately, what I want to learn how to do is drag and drop views into grid cells. I've only been coding in Swift for a few months so it would be helpful if someone with more experience points me in the right direction.
import SwiftUI
struct ContentView: View {
var input: String = "hello world"
@State var output: String = " "
var body: some View {
VStack {
Text(input)
.frame(width: 100, height: 50)
.border(Color.blue, width: 2)
.draggable(input)
Grid {
ForEach(1..<4) { row in
GridRow {
ForEach(1..<4) { column in
Text("\(row) , \(column)")
.frame(width: 100, height: 50)
.border(Color.red, width: 2)
}
}
}
}.dropDestination(for: String.self) { _, location in
output = "\(location.x), \(location.y)"
return true
}
List {
ForEach(1..<4) { i in
Text("\(i)")
.frame(width: 100, height: 50)
.border(Color.green, width: 2)
}.dropDestination(for: String.self) { _, location in
output = "\(location)"
}
}
Text(output)
.frame(width: 200, height: 50)
.border(Color.cyan, width: 2)
}
}
}