Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在macOS上的SwiftUI中将颜色从源拖放到目标_Swiftui - Fatal编程技术网

在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
            }
        }
    }
}