我有一个带有导航视图列表的应用程序,以后在应用程序中添加新元素时,该视图不会更新。初始屏幕很好,无论我如何编码,此刻一切都将触发,但除此之外,它仍然保持这种状态。在某个时候,我将我的“ 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))
}
}
答案 0 :(得分:1)
SwiftUI是您如何构建UIKit应用程序的范式转变。
想法是将“驱动”视图的数据(即View模型)与View表示关注点分开。
换句话说,如果您有一个显示ParentView
列表的ChildView(foo:Foo)
,则ParentView
的视图模型应该是Foo
对象的数组-不是ChildView
s:
struct Foo { var v: String }
class ParentVM: ObservableObject {
@Published let foos = [Foo("one"), Foo("two"), Foo("three")]
}
struct ParentView: View {
@ObservedObject var vm = ParentVM()
var body: some View {
List(vm.foos, id: \.self) { foo in
ChildView(foo: foo)
}
}
}
struct ChildView: View {
var foo: Foo
var body = Text("\(foo.v)")
}
因此,在您的情况下,请从Dice
中添加添加DiceViewList
个对象的逻辑(为了简洁起见,我为您保留特定的逻辑):
class DiceListVM: ObservableObject {
@Published var dice: [Dice] = []
func add(dice: Dice) {
dice.append(dice)
}
}
struct DiceViewList: View {
@ObservedObject var vm: DiceListVM = DiceListVM()
var body: some View {
NavigationView {
List(vm.dice) { dice in
NavigationLink(destination: DiceView(for: dice)) {
Text(dice.name)
}
}
}
}
如果您需要的数据多于Dice
中可用的数据,只需创建一个DiceVM
以及所有其他属性,例如.name
和.dice
和objectId
但是要点是:不存储和出售视图。-仅处理数据。
答案 1 :(得分:0)
在进行测试时,我意识到了问题所在。我假设在其他所有类中声明@ObservedObject var vm: DiceViewList = DiceViewList()
并在需要它的结构中声明它们会找到相同的对象,但事实并非如此!我试图将观察到的对象作为参数传递给包含“添加”按钮的子视图,现在它可以按预期工作。