从自定义标签栏视图转到全屏并返回时出现错误“在视图更新期间修改状态,这将导致未定义的行为”

时间:2020-08-08 03:09:10

标签: firebase firebase-realtime-database swiftui tabbar

我有以下可观察对象:

class DisplayDetails: ObservableObject {

    @Published var showFullScreen: Bool = false

}


class ViewRouter: ObservableObject {

    @Published var currentView = "social"

}

这是在启动时显示选项卡栏的主视图:

struct AppView: View {
    
    @ObservedObject var viewRouter = ViewRouter()

    @EnvironmentObject var displayDetails: DisplayDetails

    var body: some View {
    
        ZStack {
    
            VStack {
                
                Spacer()
                
                if self.viewRouter.currentView == "social" {
                    
                    Social()
                    
                } else if self.viewRouter.currentView == "menu" {
                    
                    Menu()
                    
                }
        
            }
        
    
            // *** HERE IS WHERE I DO THE CHECK FOR FULL SCREEN OR TAB BAR VIEW ***
            if (!displayDetails.showFullScreen) {
                      
                VStack {
                        
                    Spacer()
            
                    ZStack {
            
                        HStack {
                        
                            Button(action: {
                        
                                if (self.viewRouter.currentView != "social") {
                        
                                    self.viewRouter.currentView = "social"
                        
                                }
                        
                            }) {
                                
                                Image("Social")
                                    .resizable()
                                    .aspectRatio(contentMode: .fit)
                                    .frame(width: 30, height: 30)
                            
                           }
                           .foregroundColor(self.viewRouter.currentView == "socail" ? .black : .gray)

                           Spacer(minLength: 12)
                       
                           Button(action: {
                          
                               if (self.viewRouter.currentView != "menu") {
                            
                                   self.viewRouter.currentView = "menu"
                        
                               }
                        
                           }) {
                          
                               Image("Menu")
                                   .resizable()
                                   .aspectRatio(contentMode: .fit)
                                   .frame(width: 30, height: 30)
                        
                          }
                          .foregroundColor(self.viewRouter.currentView == "menu" ? .black : .gray)

                      }
                      .padding()
                      .padding(.horizontal, 22)
                      .background(CurvedShape())
                
                  }
                  .background(Color("Color")
                  .edgesIgnoringSafeArea(.top))
              
              }

          }
          
     }
      
}

默认情况下,如ViewRouter中所示,社交标签栏被选中

该视图如下:

struct Social: View {

    // Used to track for full display
    @EnvironmentObject var displayDetails: DisplayDetails

    var body: some View {

        NavigationView {

            List {
                  
                ForEach(self.socialStore.social, id: \.self) { social in
                    
                    NavigationLink(destination: SocialDetails()) {
                        
                        SocialCell(social: social)
                        
                    }
                }
            
            }
            .navigationBarTitle(Text("Social"))
            .padding(.bottom)
            .onAppear() {

                self.fetchsocial() // Firebase DB call to populate the list

            }

        }
        .padding(.bottom)

    }

}

最后,“社交详细信息页面”应为全屏显示,并且不包含标签栏:

struct SocialDetails: View {

    @EnvironmentObject var displayDetails: DisplayDetails


    var body: some View {

        VStack {
    
            Image("image_here" )
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: 150, height: 150)
                .clipped()
                .cornerRadius(150)
                .shadow(radius: 3)
        
            Text("User name")
                .font(.title)
                .fontWeight(.medium)
        
            Form {
        
                Section {
            
                    HStack {
                
                        Text("Phone")
                    
                        Spacer()
                    
                        Text("1234567890")
                            .foregroundColor(.gray)
                            .font(.callout)
                
                    }
                
                    HStack {
                        
                        Text("Email")
                    
                        Spacer()
                    
                        Text("sg@sg.com" /*contact.email*/)
                            .foregroundColor(.gray)
                            .font(.callout)
                
                    }
                
                    HStack {
                
                        Text("Address")
                    
                        Spacer()
                    
                        Text("123 AVE" /*contact.address*/)
                            .foregroundColor(.gray)
                            .font(.callout)
                            .frame(width: 180)
                
                    }
                    
                }
        
            }
    
        }
        .onAppear {
            
            self.displayDetails.showFullScreen.toggle()

            
        }
        .onDisappear {

            self.displayDetails.showFullScreen.toggle()
        
        }
    
    }

}

因此,当应用程序运行时,一切正常,无法在选项卡之间来回导航。 当我单击“社交”选项卡列表中的项目时,列表将滚动而不是向右滑动,我认为这是在视图“隐藏”详细视图的选项卡栏时发生的。

然后在返回链接上的返回列表变得非常时髦……这是在<<<“视图更新期间处于修改状态,这将导致未定义的行为” >>。

发生的事情真的很奇怪。该列表实际显示,但是大约一秒钟,然后再次汇总,列表为空!?

唯一的好处是,选项卡栏可以根据需要再次显示...但是我假设隐藏并显示该图像会发出警告,并暗示它给了我未定义的行为!

有人遇到过这个问题,您能够解决吗?

列表必须来自动态来源,在我的实例中为Firebase实时数据库。

***更新:

包括行为有问题的视频: https://www.dropbox.com/s/2655vdrjb796d8o/test.mov?dl=0

在观看视频时,将显示列表。当我单击列表中的项目时,它将导航到详细视图并根据需要隐藏选项卡栏。 **请注意,当它开始导航到详细视图时,列表视图会汇总列表中的项目(很奇怪)?我希望只是一张详细视图的幻灯片。当我返回时,将显示列表(就像从列表中的第一项展开一样),然后列表再次回滚到第一项中,并且屏幕最终变成空白!?

更新:

下面是我从Firebase Realtime数据库获取数据的获取函数,我不确定它是否正确:

func fetch (userId: String) {
    
    ref.child(userId).observeSingleEvent(of: .value, with: { (snapshot) in
            
        for child in snapshot.children {
                
            if let snapshot = child as? DataSnapshot,
                
                let review = Review(snapshot: snapshot) {
                    
                    self.reviews.append(review)
                
                }
                
        }

    })
            
}

0 个答案:

没有答案