New to SwiftUI... I have the following simplified code. The intended functionality is to be able to navigate between View1()
and View2()
, using a singleton class to keep track of this navigation.
I suspect that maybe I needed to add @Published
to my show_view_2
variable, but I want to keep it in App Storage. Also, I understand this isn't the best way to switch between views, but I only am using this method because it's a minimally reproduced example.
Why isn't the below code working, and how can I make it work?
class Player {
static var player = Player()
@AppStorage("show_view_2") var show_view_2: Bool = false
}
struct ContentView: View {
var body: some View {
if(Player.player.show_view_2) {
View2()
} else {
Text("Go to View2")
.onTapGesture {
Player.player.show_view_2 = true
}
}
}
}
struct View2: View {
var body: some View {
Text("Back to View1")
.onTapGesture {
Player.player.show_view_2 = false
}
}
}
For SwiftUI to know to update, Player
should be an ObservableObject
. Also, it'll need to be accessed using a property wrapper (either @StateObject
or @ObservedObject
) on the View
:
class Player : ObservableObject {
static var player = Player()
@AppStorage("show_view_2") var show_view_2: Bool = false
}
struct ContentView: View {
@StateObject private var player = Player.player
var body: some View {
if player.show_view_2 {
View2()
} else {
Text("Go to View2")
.onTapGesture {
player.show_view_2 = true
}
}
}
}
struct View2: View {
@StateObject private var player = Player.player
var body: some View {
Text("Back to View1")
.onTapGesture {
player.show_view_2 = false
}
}
}
In general, I'd recommend not using a singleton and instead passing an instance of the object explicitly between views -- this will be more testable and flexible over time:
class Player : ObservableObject {
@AppStorage("show_view_2") var show_view_2: Bool = false
}
struct ContentView: View {
@StateObject private var player = Player()
var body: some View {
if player.show_view_2 {
View2(player: player)
} else {
Text("Go to View2")
.onTapGesture {
player.show_view_2 = true
}
}
}
}
struct View2: View {
@ObservedObject var player : Player
var body: some View {
Text("Back to View1")
.onTapGesture {
player.show_view_2 = false
}
}
}