状态变量值正在丢失

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())
          
        
    


【讨论】:

以上是关于状态变量值正在丢失的主要内容,如果未能解决你的问题,请参考以下文章

PHP计算变量值出现的次数

012 变量

数据类型

变量的命名,变量值的特征及数据类型

变量常量注释

如何在 Linux 中永久导出变量?