I make an array in ContentView and I can change the context of it when someone dragging the object. In ContentView I have an array nodes.n_array that is an array of Node objects. In ForEach(in ContentView) I try to detect dragging the object and change coordinates of it. It doesn't work.
Node class:
import Foundation
import SwiftUI
class Node: Decodable, ObservableObject {
enum CodingKeys: CodingKey {
case id, x, y, text, red, green, blue, shape
}
public let id: Int
@Published var x: Double
@Published var y: Double
public let text: String
public var red: Double
public var green: Double
public var blue: Double
public var shape: Int
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
x = try container.decode(Double.self, forKey: .x)
y = try container.decode(Double.self, forKey: .y)
text = try container.decode(String.self, forKey: .text)
red = try container.decode(Double.self, forKey: .red)
green = try container.decode(Double.self, forKey: .green)
blue = try container.decode(Double.self, forKey: .blue)
shape = try container.decode(Int.self, forKey: .shape)
}
}
extension Node {
func circle() -> some View {
Circle()
.fill(Color(red: red, green: green, blue: blue))
.frame(width: 64, height: 64, alignment: .center)
.position(x: x, y: y)
}
func square() -> some View {
Rectangle()
.fill(Color(red: red, green: green, blue: blue))
.frame(width: 64, height: 64, alignment: .center)
.position(x: x, y: y)
}
@ViewBuilder func drawShape() -> some View {
switch shape{
case 1: circle()
case 2: square()
default: Text("Failed")
}
}
func label() -> some View {
return Text(text)
.font(.system(size: 30))
.bold()
.position(x: x, y: y)
.foregroundColor(Color(red: 0.25, green: 0.25, blue: 0.25))
}
}
Nodes class:
import Foundation
class Nodes: ObservableObject {
@Published var n_array: [Node]
init() {
let url = Bundle.main.url(forResource: "nodes", withExtension: "json")!
let data = try! Data(contentsOf: url)
n_array = try! JSONDecoder().decode([Node].self, from: data)
}
}
Content View:
import SwiftUI
struct ContentView: View {
@ObservedObject var nodes = Nodes()
var body: some View {
ZStack {
ForEach(0..<nodes.n_array.count) { index in
nodes.n_array[index].drawShape()
.gesture(DragGesture()
.onChanged { value in
nodes.n_array[index].x = value.translation.width
nodes.n_array[index].y = value.translation.height
}
.onEnded { value in
}
)
nodes.n_array[index].label()
}
}
}
}