Home > Software engineering >  How can I save the state of the power button when I am changing beetwen tabs in SwifUI?
How can I save the state of the power button when I am changing beetwen tabs in SwifUI?

Time:04-12

I´m making a IOS app where I have a tabview. that tabview contains 3 different views, in one of these, i have a power button which has a growing animation, but when the view is changed, the power button back to off state. I´ll show you my code:

struct MainTabView: View {
    @ObservedObject private var viewModel = MainTabViewModel()
    var body: some View {

        VStack {
            HStack {
                Text(viewModel.tabTitle).font(.largeTitle).bold().padding()
                Spacer()
            }
            Spacer()
            TabView(selection: $viewModel.selectedIndex) {
                // view where is the button which activates the service
                GPSButtonView()
                        .onTapGesture {
                            viewModel.selectedIndex = 0
                        }
                        .tabItem {
                            Image(systemName: "playpause")
                        }
                        .tag(0)
                //view where is the map view
                Text("Map")
                        .onTapGesture {
                            viewModel.selectedIndex = 1
                        }
                        .tabItem {
                            Image(systemName: "map")
                        }
                        .tag(1)
                SettingsView()
                        .onTapGesture {
                            viewModel.selectedIndex = 2
                        }
                        .tabItem {
                            Image(systemName: "gear.circle")
                        }
                        .tag(2)
            }
        }
    }
}
struct GPSButtonView: View {
    @ObservedObject var viewModel = GPSButtonViewModel()
    var body: some View {
        VStack {
            Button(
                    action: {
                        //button tapped
                        viewModel.gpsState.toggle()
                        viewModel.show.toggle()

                    }
            ) {
                Image(systemName: "power.circle.fill")
                        .resizable()
                        .frame(width: 100, height: 100)
                        .foregroundColor(viewModel.gpsState ? .green : .red)
                        .scaleEffect(viewModel.show ? 2 : 1)
                        .animation(
                                Animation.easeInOut(duration: 0.5),
                                value: viewModel.show
                        )
            }
        }
    }
}
class GPSButtonViewModel: ObservableObject {
    //properties
    @Published var gpsState = false
    @Published var show = false
}

I´ll show you too a gif of the problem: problem gif

CodePudding user response:

You shouldn't be using objects in SwiftUI like this, it's best to use structs, e.g.

struct GPSButtonConfig {
    var gpsState = false
    var show = false
}

Then do

@State var config = GPSButtonConfig()

CodePudding user response:

You could conserve the state of the button by moving the ButtonViewModel up in the hierarchy.

Add this to your MainTabView:

@StateObject var buttonViewModel = GPSButtonViewModel()

and when you call your view:

GPSButtonView(viewModel: buttonViewModel)
    .onTapGesture {
        viewModel.selectedIndex = 0
    }
    .tabItem {
        Image(systemName: "playpause")
    }
    .tag(0)
            

and important

remove the initializer from your buttonview:

struct GPSButtonView: View {
        @ObservedObject var viewModel: GPSButtonViewModel
  • Related