在内容视图 SwiftUI 中更新对象数组
Posted
技术标签:
【中文标题】在内容视图 SwiftUI 中更新对象数组【英文标题】:Updating array of objects in Content View 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()
【问题讨论】:
【参考方案1】:嵌套的ObservableObject
s 在 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
注意:你还需要更多的逻辑来进行拖动,但这超出了这个问题的直接范围——你会在拖动开始时看到项目跳转,因为你需要存储初始翻译
【讨论】:
以上是关于在内容视图 SwiftUI 中更新对象数组的主要内容,如果未能解决你的问题,请参考以下文章
外部模型对象的 SwiftUI 数据流和 UI 更新,其值发生变化但 id 相同