如何防止其他视图刷新状态更改swiftUI

时间:2020-09-03 05:39:54

标签: swift xcode swiftui combine

我在主视图中有一个底部导航视图,我想通过在ViewModel中定义的@published变量隐藏在某些内部视图中,但是当我更改变量的值时,它会覆盖整个主体在主视图中刷新并引起一些问题(数据丢失)。我只想刷新底部导航的状态,而不是整个身体。这是我的代码:

MainView

struct MainView: View {
@ObservedObject var viewModel = MainViewModel()


var body: some View {
    ZStack {
        VStack{
            content
        }
        
            VStack {
                Spacer()
                BottomNavigationView(mainViewModel: self.viewModel)
                        .padding(.horizontal)
            }.opacity(viewModel.isBottomNavigationVisible ? 1 : 0)


    }
}

var content: some View {
    switch self.viewModel.currentView {
    case .plan:
        return PlanMainView(mainViewModel: viewModel).eraseToAnyView()
    case .me:
        return MeMainView(mainViewModel: viewModel).eraseToAnyView()
    case .onBoarding:
        return OnBoardingHome(mainViewModel: viewModel).eraseToAnyView()
}}

MainViewModel

class MainViewModel: ObservableObject {
@Published private(set) var currentView: Modules = .main
@Published var isBottomNavigationVisible: Bool = true


func hideBottomBar() {
    self.isBottomNavigationVisible = false
}

func showBottomBar() {
    self.isBottomNavigationVisible = true
}

func GoToView(view: Modules) {
    self.currentView = view
}}

MeMainView

这是我要在onAppear中隐藏底部导航的视图

struct MeMainView: View {
@ObservedObject var mainViewModel:MainViewModel


var body: some View {
    ZStack {
       Text("MewView")
    }.onAppear{
        self.mainViewModel.hideBottomBar()
    }
}}

1 个答案:

答案 0 :(得分:1)

content而不是可计算的属性移到单独的视图中,因为它没有任何更改,因此不会刷新

    VStack{
        BodyView(viewModel: viewModel)
    }

struct BodyView: View {
   @ObservedObject var viewModel: MainViewModel

   var body: some View {
      switch self.viewModel.currentView {
      case .plan:
        return PlanMainView(mainViewModel: viewModel).eraseToAnyView()
      case .me:
        return MeMainView(mainViewModel: viewModel).eraseToAnyView()
      case .onBoarding:
        return OnBoardingHome(mainViewModel: viewModel).eraseToAnyView()
  }
}