我有一个带有导航视图列表的应用程序,当应用程序中稍后添加新元素时,该列表不会更新。最初的屏幕是好的,一切都得到触发,在这一刻,无论我如何编码,但除此之外,它保持这种方式。在某个时候,我把我的“init”方法作为一个.onappear,动态元素不会进来,但是当我在应用程序中来回移动时,静态元素会被多次添加,虽然这不再是我代码的一部分。
这里我的内容视图看起来像什么,我试图将导航视图部分移动到具有已发布的var的类中,如果它有帮助,视觉上它不会改变任何东西,也不会帮助。
struct ContentView: View {
@ObservedObject var diceViewList = DiceViewList()
var body: some View {
VStack{
Text("Diceimator").padding()
diceViewList.body
Text("Luck Selector")
}
}
}
和DiceViewList类
import Foundation
import SwiftUI
class DiceViewList: ObservableObject {
@Published var list = [DiceView]()
init() {
list.append(DiceView(objectID: "Generic", name: "Generic dice set"))
list.append(DiceView(objectID: "Add", name: "Add a new dice set"))
// This insert is a simulation of what add() does with the same exact values. it does get added properly
let pos = 1
let id = 1
self.list.insert(DiceView(objectID: String(id), dice: Dice(name: String("Dice"), face: 1, amount: 1), name: "Dice"), at: pos)
}
var body: some View {
NavigationView {
List {
ForEach(self.list) { dView in
NavigationLink(destination: DiceView(objectID: dView.id, dice: dView.dice, name: dView.name)) {
HStack { Text(dView.name) }
}
}
}
}
}
func add(dice: Dice) {
let pos = list.count - 1
let id = list.count - 1
self.list.insert(DiceView(objectID: String(id), dice: dice, name: dice.name), at: pos)
}
}
我正在开发最新的Xcode 11,以防万一
**编辑:**根据建议编辑代码,问题没有改变
struct ContentView: View {
@ObservedObject var vm: DiceViewList = DiceViewList()
var body: some View {
NavigationView {
List(vm.customlist) { dice in
NavigationLink(destination: DiceView(dice: dice)) {
Text(dice.name)
}
}
}
}
}
DiceViewList
类
class DiceViewList: ObservableObject {
@Published var customlist: [Dice] = []
func add(dice: Dice) {
self.customlist.append(dice)
}
init() {
customlist.append(Dice(objectID: "0", name: "Generic", face: 1, amount: 1))
customlist.append(Dice(objectID: "999", name: "AddDice", face: 1, amount: 1))
}
}
3条答案
按热度按时间qncylg1j1#
SwiftUI是一个范式转变,从你如何构建UIKit应用程序。
其思想是将“驱动”视图的数据(即视图模型)与视图表示关注点分离。
换句话说,如果你有一个
ParentView
,它显示了一个ChildView(foo:Foo)
的列表,那么ParentView
的视图模型应该是一个Foo
对象的数组,而不是ChildView
s:因此,在您的示例中,将添加
Dice
对象的逻辑与DiceViewList
分开(为了简洁起见,我随意使用您的特定逻辑):如果您需要比
Dice
中可用的数据更多的数据,只需创建一个具有所有其他属性的DiceVM
,如.name
和.dice
和objectId
。但结论是:不要存储和出售视图。-只处理数据。
ttvkxqim2#
在测试的时候,我意识到了这个问题。我假设在每个其他类和结构中声明
@ObservedObject var vm: DiceViewList = DiceViewList()
会让它们找到相同的对象,但事实并非如此!我尝试将观察到的对象作为参数传递给包含“add”按钮的子视图,现在它可以正常工作了。tp5buhyn3#
@NewDev的答案对于具体问题是正确的,但我也想为我的问题提供一个答案。
我嵌套了
@ObservableObject
类和@Published
属性:并且每当我-在这个例子中-点击按钮来切换内部对象的
myBool
值时,视图没有刷新。TLDR:嵌套的
@ObservableObject
情况可以通过将内部引用传递给子视图来解决,子视图应该将其存储为@ObservedObject
属性:阅读更多here