"Modifying state during view update, this will cause undefined behavior" 的奇怪问题
Strange issue of "Modifying state during view update, this will cause undefined behavior"
目标:拥有一个 SwiftUI 架构,其中“添加新项目”和“编辑现有项目”由同一视图 (EditItemView) 解决。但是,出于某种原因,当我这样做时,运行时代理会抱怨“在视图更新期间修改状态,这将导致未定义的行为”。
这是我要使用的代码,它确保项目的编辑和添加新项目由同一个 EditItemView 处理:
var body: some View {
NavigationView
{
ScrollView
{
LazyVGrid(columns: my_columns)
{
ForEach(items, id: \.id)
{
let item = [=11=]
// THIS LINE TO EDIT AN EXISTING ITEM
NavigationLink(destination: EditItemView(item: item))
{
ItemView(item: item)
}
}
}
}
.navigationBarItems(trailing:
// THIS LINE TO ADD A NEW ITEM:
NavigationLink(destination: EditItemView(item: Data.singleton.createItem(name: "New item", value: 5.0))
{
Image(systemName: "plus")
}
)
}
}
它不起作用,导致上面突出显示的问题。我被迫将编辑和添加的功能分离到两个不同的视图中,这样就可以工作了:
var body: some View {
NavigationView
{
ScrollView
{
LazyVGrid(columns: my_columns)
{
ForEach(items, id: \.id)
{
let item = [=12=]
// THIS LINE TO EDIT AN EXISTING ITEM
NavigationLink(destination: EditItemView(item: item))
{
ItemView(item: item)
}
}
}
}
.sheet(isPresented: $isPresented)
{
// FORCED TO USE SEPARATE VIEW
AddItemView { name, value in
_ = Data.singleton.createItem(name: name, value: value)
self.isPresented = false
}
}
.navigationBarItems(trailing: Button(action: { self.isPresented.toggle()}) { Image(systemName: "plus")})
}
}
我不明白为什么第一个版本中的代码被认为是在更新视图时修改状态,因为对我来说,它是顺序的:创建新项目然后为该项目显示视图。
有什么想法吗?
NavigationLink
的目的地 不是 延迟呈现,这意味着它会在 NavigationLink
本身呈现时呈现 - 而不是在点击时呈现.
sheet
代码,根据平台和 SwiftUI 版本,可能有相同的问题,但显然在您使用的版本中没有。或者,您提供给 AddItemView
的闭包不会立即 运行 -- 因为您没有包含代码,所以不清楚。
要解决第一种方法中的问题,您可以使用以下提供惰性 NavigationLink
的 SO 答案:
目标:拥有一个 SwiftUI 架构,其中“添加新项目”和“编辑现有项目”由同一视图 (EditItemView) 解决。但是,出于某种原因,当我这样做时,运行时代理会抱怨“在视图更新期间修改状态,这将导致未定义的行为”。
这是我要使用的代码,它确保项目的编辑和添加新项目由同一个 EditItemView 处理:
var body: some View {
NavigationView
{
ScrollView
{
LazyVGrid(columns: my_columns)
{
ForEach(items, id: \.id)
{
let item = [=11=]
// THIS LINE TO EDIT AN EXISTING ITEM
NavigationLink(destination: EditItemView(item: item))
{
ItemView(item: item)
}
}
}
}
.navigationBarItems(trailing:
// THIS LINE TO ADD A NEW ITEM:
NavigationLink(destination: EditItemView(item: Data.singleton.createItem(name: "New item", value: 5.0))
{
Image(systemName: "plus")
}
)
}
}
它不起作用,导致上面突出显示的问题。我被迫将编辑和添加的功能分离到两个不同的视图中,这样就可以工作了:
var body: some View {
NavigationView
{
ScrollView
{
LazyVGrid(columns: my_columns)
{
ForEach(items, id: \.id)
{
let item = [=12=]
// THIS LINE TO EDIT AN EXISTING ITEM
NavigationLink(destination: EditItemView(item: item))
{
ItemView(item: item)
}
}
}
}
.sheet(isPresented: $isPresented)
{
// FORCED TO USE SEPARATE VIEW
AddItemView { name, value in
_ = Data.singleton.createItem(name: name, value: value)
self.isPresented = false
}
}
.navigationBarItems(trailing: Button(action: { self.isPresented.toggle()}) { Image(systemName: "plus")})
}
}
我不明白为什么第一个版本中的代码被认为是在更新视图时修改状态,因为对我来说,它是顺序的:创建新项目然后为该项目显示视图。
有什么想法吗?
NavigationLink
的目的地 不是 延迟呈现,这意味着它会在 NavigationLink
本身呈现时呈现 - 而不是在点击时呈现.
sheet
代码,根据平台和 SwiftUI 版本,可能有相同的问题,但显然在您使用的版本中没有。或者,您提供给 AddItemView
的闭包不会立即 运行 -- 因为您没有包含代码,所以不清楚。
要解决第一种方法中的问题,您可以使用以下提供惰性 NavigationLink
的 SO 答案: