'how to prevent other views refreshing in state change swiftUI
I have a bottom navigation view in my main View that I want to hide in some of the inner views by a @published variable that defined in ViewModel, but when I change the value of the variable all of the body refreshes in the main view and cause some problems(losing data). I want just to refresh the state of the bottom navigation, not the entire body. here is my code:
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
this is the view that I want to hide the bottom navigation in onAppear
struct MeMainView: View {
@ObservedObject var mainViewModel:MainViewModel
var body: some View {
ZStack {
Text("MewView")
}.onAppear{
self.mainViewModel.hideBottomBar()
}
}}
Solution 1:[1]
Instead of computable property move content into separated view, as nothing changed for it so it will not be refreshed
VStack{
BodyView(viewModel: viewModel)
}
and
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()
}
}
Solution 2:[2]
var myDict: [String: Double] = [:]
var body: some View {
HStack(alignment: .top) {
Button(action: {
self.myDict[self.tag] = amountValue
})
}
I have two user when I select 1st user and save some value to myDict, I want to add value for 2nd user to MyDict when i select 2nd user (means count of MyDict should be 2) but when i select 2nd user view is refreshing and value of 1st user is replace by 2nd user (means count of MyDict should be 1).
Is there any way so that i can have both the value in dict and not refresh?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Asperi |
| Solution 2 | New iOS Dev |
