gpt4 book ai didi

ios - SwiftUI View 未基于 @ObservedObject 更新

转载 作者:行者123 更新时间:2023-12-01 15:30:31 25 4
gpt4 key购买 nike

在下面的代码中,观察到的对象会更新,但观察它的 View 不会。知道为什么吗?

该代码在屏幕上显示 10 个数字 (0..<10) 和一个按钮。每当按下按钮时,它会随机选择 10 个数字之一并翻转其可见性(可见→隐藏,反之亦然)。

打印语句显示按钮正在更新数字,但 View 没有相应更新。我知道更新数组中的值不会改变数组值本身,所以我使用手册 objectWillChange.send()称呼。我原以为应该触发更新,但屏幕永远不会改变。

任何想法?我会对使用 NumberLine 的解决方案感兴趣作为一个类,或作为一个结构,或不使用 NumberLine完全键入,而只是在 ContentView 中使用数组变量结构。

Screenshot

这是代码:

import SwiftUI

struct ContentView: View {

@ObservedObject var numberLine = NumberLine()

var body: some View {
VStack {
HStack {
ForEach(0 ..< numberLine.visible.count) { number in
if self.numberLine.visible[number] {
Text(String(number)).font(.title).padding(5)
}
}
}.padding()

Button(action: {
let index = Int.random(in: 0 ..< self.numberLine.visible.count)
self.numberLine.objectWillChange.send()
self.numberLine.visible[index].toggle()
print("\(index) now \(self.numberLine.visible[index] ? "shown" : "hidden")")
}) {
Text("Change")
}.padding()
}
}
}

class NumberLine: ObservableObject {
var visible: [Bool] = Array(repeatElement(true, count: 10))
}

最佳答案

@ObservedObject一切都很好……让我们分析一下……
迭代 1:
无需更改代码并仅添加以下行(显示为 visible 数组的文本当前状态)

VStack { // << right below this
Text("\(numberLine.visible.reduce(into: "") { $0 += $1 ? "Y" : "N"} )")
运行,你会看到 Text已更新,因此可观察对象有效
demo
迭代 2:
删除 self.numberLine.objectWillChange.send()并使用默认值 @Published View 模型中的模式
class NumberLinex: ObservableObject {
@Published var visible: [Bool] = Array(repeatElement(true, count: 10))
}
运行,您会看到更新的工作方式与上面的第一个演示相同。
*但是... ForEach 中的主要数字仍然没有更新...是的,因为 ForEach 中的问题- 你使用了带有 Range 的构造函数生成 常数 查看群 按设计 (记录在案!)。
!!这就是原因 - 你需要动态 ForEach ,但对于该模型需要更改。
迭代 3 - 最终:
动态 ForEach构造函数要求迭代的数据元素是可识别的,所以我们需要 struct 作为模型和更新的 View 模型。
这是最终解决方案和演示(使用 Xcode 11.4/iOS 13.4 测试)
demo2
struct ContentView: View {

@ObservedObject var numberLine = NumberLine()

var body: some View {
VStack {
HStack {
ForEach(numberLine.visible, id: \.id) { number in
Group {
if number.visible {
Text(String(number.id)).font(.title).padding(5)
}
}
}
}.padding()

Button("Change") {
let index = Int.random(in: 0 ..< self.numberLine.visible.count)
self.numberLine.visible[index].visible.toggle()
}.padding()
}
}
}

class NumberLine: ObservableObject {
@Published var visible: [NumberItem] = (0..<10).map { NumberItem(id: $0) }
}

struct NumberItem {
let id: Int
var visible = true
}
backup

关于ios - SwiftUI View 未基于 @ObservedObject 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60956270/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com