状态变量值正在丢失
Posted
技术标签:
【中文标题】状态变量值正在丢失【英文标题】:State variable value is being lost 【发布时间】:2021-01-11 00:52:54 【问题描述】:我在 ios 1 中运行以下代码。当按下“视图 A”按钮时,状态变量 nextModalView2 设置为 NextModalView2.a 但是当执行 Sheet() 调用时,nextModalView2 的值被重置为 .none .
这怎么可能?
此外,如果您查看屏幕截图,您会看到调试器控制台面板显示的 nextModalView2 值与调试器变量面板中显示的值不同。怎么样?
enum NextModalView2
case none
case a
case b
struct Menu2: View
@State private var isShowModally = false
@State private var nextModalView2 = NextModalView2.none
var body: some View
VStack(alignment: .center)
Button(action:
self.isShowModally = true
self.nextModalView2 = .a
print("self.nextModalView = \(self.nextModalView2)")
) Text("View A")
Divider()
Button(action:
self.isShowModally = true
self.nextModalView2 = .b
) Text("View B")
.padding(.top, 20)
.sheet(isPresented: $isShowModally)
Group
if self.nextModalView2 == .a
// case NextModalView2.a:
AnyView(Text("A"))
if self.nextModalView2 == NextModalView2.b
AnyView(Text("B"))
if self.nextModalView2 == NextModalView2.none
AnyView(EmptyView())
【问题讨论】:
当您的视图出现在屏幕上时,会配置 .sheet() 修饰符。所以在 init() 上,.sheet() 将返回 .none。解决方案是避免在工作表关闭中打开内容。我在这里为此提供了 2 个超级简单的解决方案:***.com/questions/65416673/… 【参考方案1】:我们需要在这种情况下使用sheet(item:
修饰符,它适用于每个选择。
这里有一个解决方案。使用 Xcode 12.1 / iOS 14.1 测试。
enum NextModalView2: Identifiable
var id: NextModalView2 self
case none
case a
case b
struct Menu2: View
@State private var nextModalView2: NextModalView2?
var body: some View
VStack(alignment: .center)
Button(action:
self.nextModalView2 = .a
print("self.nextModalView = \(self.nextModalView2 ?? .none)")
) Text("View A")
Divider()
Button(action:
self.nextModalView2 = .b
) Text("View B")
.padding(.top, 20)
.sheet(item: $nextModalView2) item in
switch item
case .a:
Text("A")
case .b:
Text("B")
default:
EmptyView()
【讨论】:
这似乎是一个不错的解决方案。关于为什么调试器变量面板没有显示正确的属性值的任何想法(如控制台调试器中正确显示的那样?【参考方案2】:我在 SwiftUI 中使用工作表的经验是,您可以获得一些非常有趣的行为(尤其是在 Catalyst 上)。我的怀疑是工作表在第一次运行时被渲染(当你的值是 none
时),然后当你的 @State
变量发生变化时实际上并没有被调用来更新,可能是因为在幕后,工作表是包裹在 UIViewControllerRepresentable 之类的东西中,当你认为它们会传递时,值并没有传递。
我提取了您的工作表视图并将参数更改为@Binding,即使您可能不需要双向通信,因为它似乎可以解决此问题:
enum NextModalView2
case none
case a
case b
struct ContentView: View
@State private var isShowModally = false
@State private var nextModalView2 = NextModalView2.none
var body: some View
VStack(alignment: .center)
Button(action:
self.nextModalView2 = .a
self.isShowModally = true
print("self.nextModalView = \(self.nextModalView2)")
) Text("View A")
Divider()
Button(action:
self.nextModalView2 = .b
self.isShowModally = true
) Text("View B")
.padding(.top, 20)
.sheet(isPresented: $isShowModally)
SheetContent(nextModalView2: $nextModalView2)
struct SheetContent : View
@Binding var nextModalView2 : NextModalView2
var body: some View
Group
if self.nextModalView2 == .a
AnyView(Text("A"))
if self.nextModalView2 == NextModalView2.b
AnyView(Text("B"))
if self.nextModalView2 == NextModalView2.none
AnyView(EmptyView())
【讨论】:
以上是关于状态变量值正在丢失的主要内容,如果未能解决你的问题,请参考以下文章