How can I drag and drop a color from a source to a destination and have it stay? I currently have code working that does this on a temporary basis (changes color of destination on drag from source) but it quickly changes back on mouse up. So how can I have the color-change stay on mouse up over a specific cell and be able to change that cell again on future drags on mouse up over that specific cell? I am basing my current code off of here.

import SwiftUI
struct ContentView: View {
var body: some View {
HStack {
ColorSource(color: .purple, color2: .orange)
Spacer()
ColorSource(color: .blue, color2: .pink)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
struct DestinationDataKey: PreferenceKey {
typealias Value = [DestinationData]
static var defaultValue: [DestinationData] = []
static func reduce(value: inout [DestinationData], nextValue: () -> [DestinationData]) {
value.append(contentsOf: nextValue())
}
}
struct DestinationData: Equatable {
let destination: Int
let frame: CGRect
}
struct DestinationDataSetter: View {
let destination: Int
var body: some View {
GeometryReader { geometry in
Rectangle()
.fill(Color.clear)
.preference(key: DestinationDataKey.self,
value: [DestinationData(destination: self.destination, frame: geometry.frame(in: .global))])
}
}
}
struct DestinationView: View {
@Binding var active: Int
let label: String
let id: Int
let color: Color
var body: some View {
Text(label).padding(10).background(self.active == id ? color : Color.green)
.background(DestinationDataSetter(destination: id))
}
}
struct ColorSource: View {
@State var active = 0
@State var destinations: [Int: CGRect] = [:]
@State var color:Color
@State var color2:Color
@State var draggingFirstColor:Bool = false
@State var draggingSecondColor:Bool = false
var body: some View {
VStack {
Text("Drag From Here").padding().background(color)
.gesture(DragGesture(minimumDistance: 0.1, coordinateSpace: .global)
.onChanged { value in
self.draggingFirstColor = true
self.active = 0
for (id, frame) in self.destinations {
if frame.contains(value.location) {
self.active = id
}
}
}
.onEnded { value in
// do something on drop
self.active = 0
self.draggingFirstColor = false
}
)
Text("Drag From Here").padding().background(color2)
.gesture(DragGesture(minimumDistance: 0.1, coordinateSpace: .global)
.onChanged { value in
self.draggingSecondColor = true
self.active = 0
for (id, frame) in self.destinations {
if frame.contains(value.location) {
self.active = id
}
}
}
.onEnded { value in
// do something on drop
self.active = 0
self.draggingSecondColor = false
}
)
Divider()
DestinationView(active: $active, label: "Drag Over Me", id: 1, color: (draggingFirstColor ? color : (draggingSecondColor ? color2 : Color.green)))
DestinationView(active: $active, label: "Drag Over Me", id: 2, color: (draggingFirstColor ? color : (draggingSecondColor ? color2 : Color.green)))
DestinationView(active: $active, label: "Drag Over Me", id: 3, color: (draggingFirstColor ? color : (draggingSecondColor ? color2 : Color.green)))
DestinationView(active: $active, label: "Drag Over Me", id: 4, color: (draggingFirstColor ? color : (draggingSecondColor ? color2 : Color.green)))
}.onPreferenceChange(DestinationDataKey.self) { preferences in
for p in preferences {
self.destinations[p.destination] = p.frame
}
}
}
}

