I want to create a global variable for showing a loadingView, I tried lots of different ways but could not figure out how to. I need to be able to access this variable across the entire application and update the MotherView file when I change the boolean for the singleton.
struct MotherView: View {
@StateObject var viewRouter = ViewRouter()
var body: some View {
if isLoading { //isLoading needs to be on a singleton instance
Loading()
}
switch viewRouter.currentPage {
case .page1:
ContentView()
case .page2:
PostList()
}
}
}
struct MotherView_Previews: PreviewProvider {
static var previews: some View {
MotherView(viewRouter: ViewRouter())
}
}
I have tried the below singleton but it does not let me update the shared instance? How do I update a singleton instance?
struct LoadingSingleton {
static let shared = LoadingSingleton()
var isLoading = false
private init() { }
}
2
Answers
Make your singleton a
ObservableObject
with@Published
properties:I should mention that in SwiftUI, it’s common to use
.environmentObject
to pass a dependency through the view hierarchy rather than using a singleton — it might be worth looking into.First, make
LoadingSingleton
a class that adheres to theObservableObject
protocol. Use the@Published
property wrapper onisLoading
so that your SwiftUI views update when it’s changed.Then, put
LoadingSingleton
in yourSceneDelegate
and hook it into your SwiftUI views viaenvironmentObject()
:To enable your SwiftUI views to update when changing
isLoading
, declare a variable in the view’s struct, like this:When you want to change the value of
isLoading
, just access it viaSceneDelegate.singleton.isLoading
, or, inside a SwiftUI view, viasingleton.isLoading
.