【问题标题】:Updating array of objects in Content View SwiftUI在内容视图 SwiftUI 中更新对象数组
【发布时间】:2021-12-27 21:31:13
【问题描述】:

我在 ContentView 中创建了一个数组,当有人拖动对象时我可以更改它的上下文。在 ContentView 中,我有一个数组 nodes.n_array,它是一个 Node 对象数组。在 ForEach(in ContentView) 我尝试检测拖动对象并更改它的坐标。它不起作用。

节点类:

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

节点类:

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

内容视图:

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()
            }
        }
    }
}

【问题讨论】:

    标签: arrays swift class swiftui updating


    【解决方案1】:

    嵌套的ObservableObjects 在 SwiftUI 中不起作用,除非您通过调用 objectWillChange 手动将状态传播回父对象。

    通常,标准路线是为您的模型使用struct,然后让ObservableObject 父级管理数组。

    如果您将模型更改为以下内容,您将看到拖动开始更新:

    struct Node: Decodable {
        public let id: Int
        var x: Double
        var y: Double
        public let text: String
        public var red: Double
        public var green: Double
        public var blue: Double
        public var shape: Int
    }
    

    注意:你还需要更多的逻辑来进行拖动,但这超出了这个问题的直接范围——你会在拖动开始时看到项目跳转,因为你需要存储初始翻译

    【讨论】:

      猜你喜欢
      • 2020-10-29
      • 1970-01-01
      • 1970-01-01
      • 2021-03-26
      • 2021-03-30
      • 1970-01-01
      • 2021-02-26
      • 2021-06-01
      • 2022-12-15
      相关资源
      最近更新 更多