So this is a simplified version of my app which have I tried that reproduces the error, I have a TabView with 2 Tabs(HomeView &OrderView), if I placed the selection index using viewModel, everytime I go to OrderView and return back to HomeView, the loaded view in HomeView will be gone, this goes the same for all and any other views in other tabs.
There is no error log whatsoever in the debugging logs, the API fetch perfectly and the data is there if I print them, the variables is all fine too, but the UI only appearing at first load (before switching tab), then it is gone after I switch tab.
If I removed the tab selection index or placed the index in the ContentView with @State, it all works perfectly, but I need to put the index in ViewModel so I can modify the index from another View.
What is wrong with this behaviour? Thank you very much in advance
ContentView.swift
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@ObservedObject var viewModel = HomeViewModel()
var body: some View {
NavigationView {
TabView(selection: self.$viewModel.homeTabSelected) {
HomeView(homeVm: self.viewModel).tabItem {
VStack {
Image(systemName: "house")
Text("Home")
}
}.tag(0)
OrderView().tabItem {
VStack {
Image(systemName: "note.text")
Text("Order")
}
}.tag(1)
}
}
}
}
HomeViewModel.swift
class HomeViewModel: ObservableObject {
@Published var homeTabSelected = 0
func changeTab() {
self.homeTabSelected = 2
}
}
HomeView.swift
struct HomeView: View {
@ObservedObject var homeVm: HomeViewModel
var body: some View {
ZStack {
VStack {
ScrollView {
VStack(alignment: .leading) {
ZStack(alignment: .top) {
VStack(alignment: .leading) {
HStack {
Text("Good Afternoon")
.foregroundColor(Color.white)
}
Spacer().frame(height: 25)
}.offset(y: 50)
.frame(maxWidth: .infinity, alignment: .topLeading)
.padding(.horizontal, 20)
}
Group {
MenuListView(homeVm: self.homeVm)
}
}
}
}.edgesIgnoringSafeArea(.top)
}.navigationBarHidden(true)
.background(Color("c_fff"))
}
}
MenuListView.swift
struct MenuListView: View {
@ObservedObject var viewModel = MenuListViewModel()
@ObservedObject var homeVm: HomeViewModel
var body: some View {
VStack {
Group {
VStack(alignment: .leading) {
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(self.viewModel.category, id: \.self) { cat in
Button(action: {
}) {
Text(cat.categoryTitle.capitalized)
.padding(.horizontal, 15)
.padding(.vertical, 8)
// This will not appear after I changed tab and return to HomeView
}
}
}
}
}
}
.onAppear {
self.viewModel.getMenuList()
}
}
}
MenuListViewModel.swift
import Combine
import SwiftUI
class MenuListViewModel: ObservableObject, ModelService {
var apiSession: APIService
@Published var menu = [MenuListItem]()
@Published var category = [CategoryListItem]()
@Published var promo = [HomePromo]()
@Published var categorySelected = "promo"
var cancellables = Set<AnyCancellable>()
init(apiSession: APIService = APISession()) {
self.apiSession = apiSession
}
func getMenuList() {
let cancellable = self.getMenuList()
.sink(receiveCompletion: { result in
switch result {
case .failure(let error):
print("Handle error menu: \(error)")
case .finished:
break
}
}) { (menu) in
self.menu = menu.products
self.category = menu.category
self.promo = menu.promos
}
cancellables.insert(cancellable)
}
}
so as I have screenshot, at first app start, the the data is loaded and properly loaded in the View, then if I click on the second tab, and go back to first tab, the view is gone (the data & all variables loaded correctly in the log, also no error log whatsoever)