在macOS上的SwiftUI中将颜色从源拖放到目标
如何将颜色从源拖放到目标并保持不变?我目前有一些代码可以临时完成这项工作(从源代码拖动时更改目标的颜色),但在鼠标向上移动时会很快更改。那个么,我怎样才能让颜色的变化保持在鼠标悬停在一个特定的单元格上,并且能够在鼠标悬停在该特定单元格上时再次改变该单元格?我现在的代码是基于在macOS上的SwiftUI中将颜色从源拖放到目标,swiftui,Swiftui,如何将颜色从源拖放到目标并保持不变?我目前有一些代码可以临时完成这项工作(从源代码拖动时更改目标的颜色),但在鼠标向上移动时会很快更改。那个么,我怎样才能让颜色的变化保持在鼠标悬停在一个特定的单元格上,并且能够在鼠标悬停在该特定单元格上时再次改变该单元格?我现在的代码是基于 只是不重置拖动颜色结束。。。或者将其存储在某个地方(比如在模型中,也可以在目的地中使用) 基于Asperi的响应,我实现了存储颜色的功能。我使用一个带有变量的枚举来记住上次拖动的颜色,并使用一个颜色数组来根据上次点击的颜
只是不重置拖动颜色结束。。。或者将其存储在某个地方(比如在模型中,也可以在目的地中使用)
基于Asperi的响应,我实现了存储颜色的功能。我使用一个带有变量的枚举来记住上次拖动的颜色,并使用一个颜色数组来根据上次点击的颜色存储和检索单元格背景颜色:
import SwiftUI
struct ContentView: View {
@State var permanentColoring: [Color] = [.clear,.clear,.clear,.clear,.clear,.clear,.clear,.clear,.clear,.clear]
@State var lastColorDragged:colorsDragged = .none
var body: some View {
HStack {
ColorSource(color: .purple, color2: .orange, permanentColoring: self.$permanentColoring, lastColorDragged: self.lastColorDragged)
Spacer()
ColorSource(color: .blue, color2: .pink, permanentColoring: self.$permanentColoring, lastColorDragged: self.lastColorDragged)
}
.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
let color2: Color
@Binding var permanentColoring:[Color]
@Binding var lastColorDragged:colorsDragged
var body: some View {
Text(label).padding(10).background( ((self.active == id) ) ? (self.lastColorDragged == .first ? color : (self.lastColorDragged == .second ? color2 : .yellow)) : self.permanentColoring[self.id])
.background(DestinationDataSetter(destination: id))
.onTapGesture {
if(self.lastColorDragged == .first) {
print("First color dragged: \(self.color) and not \(self.color2)")
self.permanentColoring[self.id] = self.color
print(self.permanentColoring[self.id])
}
else if(self.lastColorDragged == .second){
print("Second color dragged: \(self.color2) and not \(self.color)")
self.permanentColoring[self.id] = self.color2
print(self.permanentColoring[self.id])
}
}
}
}
enum colorsDragged {
case first, second, none
}
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
@Binding var permanentColoring:[Color]
@State var lastColorDragged:colorsDragged
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.lastColorDragged = colorsDragged.first
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.lastColorDragged = colorsDragged.second
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: self.color, color2: self.color2, permanentColoring: self.$permanentColoring, lastColorDragged: self.$lastColorDragged)
DestinationView(active: $active, label: "Drag Over Me", id: 2, color: self.color, color2: self.color2, permanentColoring: self.$permanentColoring, lastColorDragged: self.$lastColorDragged)
DestinationView(active: $active, label: "Drag Over Me", id: 3, color: self.color, color2: self.color2, permanentColoring: self.$permanentColoring, lastColorDragged: self.$lastColorDragged)
DestinationView(active: $active, label: "Drag Over Me", id: 4, color: self.color, color2: self.color2, permanentColoring: self.$permanentColoring, lastColorDragged: self.$lastColorDragged)
}.onPreferenceChange(DestinationDataKey.self) { preferences in
for p in preferences {
self.destinations[p.destination] = p.frame
}
}
}
}
有没有办法防止新拖动时颜色消失(例如,使单元格1变为紫色,单元格2变为橙色,单元格3变为橙色,单元格4变为紫色)?
.onEnded { value in
// do something on drop
// self.active = 0
// self.draggingFirstColor = false // same for second
}
import SwiftUI
struct ContentView: View {
@State var permanentColoring: [Color] = [.clear,.clear,.clear,.clear,.clear,.clear,.clear,.clear,.clear,.clear]
@State var lastColorDragged:colorsDragged = .none
var body: some View {
HStack {
ColorSource(color: .purple, color2: .orange, permanentColoring: self.$permanentColoring, lastColorDragged: self.lastColorDragged)
Spacer()
ColorSource(color: .blue, color2: .pink, permanentColoring: self.$permanentColoring, lastColorDragged: self.lastColorDragged)
}
.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
let color2: Color
@Binding var permanentColoring:[Color]
@Binding var lastColorDragged:colorsDragged
var body: some View {
Text(label).padding(10).background( ((self.active == id) ) ? (self.lastColorDragged == .first ? color : (self.lastColorDragged == .second ? color2 : .yellow)) : self.permanentColoring[self.id])
.background(DestinationDataSetter(destination: id))
.onTapGesture {
if(self.lastColorDragged == .first) {
print("First color dragged: \(self.color) and not \(self.color2)")
self.permanentColoring[self.id] = self.color
print(self.permanentColoring[self.id])
}
else if(self.lastColorDragged == .second){
print("Second color dragged: \(self.color2) and not \(self.color)")
self.permanentColoring[self.id] = self.color2
print(self.permanentColoring[self.id])
}
}
}
}
enum colorsDragged {
case first, second, none
}
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
@Binding var permanentColoring:[Color]
@State var lastColorDragged:colorsDragged
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.lastColorDragged = colorsDragged.first
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.lastColorDragged = colorsDragged.second
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: self.color, color2: self.color2, permanentColoring: self.$permanentColoring, lastColorDragged: self.$lastColorDragged)
DestinationView(active: $active, label: "Drag Over Me", id: 2, color: self.color, color2: self.color2, permanentColoring: self.$permanentColoring, lastColorDragged: self.$lastColorDragged)
DestinationView(active: $active, label: "Drag Over Me", id: 3, color: self.color, color2: self.color2, permanentColoring: self.$permanentColoring, lastColorDragged: self.$lastColorDragged)
DestinationView(active: $active, label: "Drag Over Me", id: 4, color: self.color, color2: self.color2, permanentColoring: self.$permanentColoring, lastColorDragged: self.$lastColorDragged)
}.onPreferenceChange(DestinationDataKey.self) { preferences in
for p in preferences {
self.destinations[p.destination] = p.frame
}
}
}
}