I built a LoadingView
with SwiftUI for showing some loading stuff in my app while I'm fetching remote data from an API. I am on Xcode Version 11.0 beta 5.
This is the LoadingView
:
struct LoadingView<Content>: View where Content: View {
@Binding var isShowing: Bool
var content: () -> Content
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .center) {
self.content()
.disabled(self.isShowing)
.blur(radius: self.isShowing ? 3 : 0)
VStack {
Text("Loading...")
ActivityIndicator(isAnimating: .constant(true), style: .large)
}
.frame(width: geometry.size.width / 2,
height: geometry.size.height / 5)
.background(Color.white)
.foregroundColor(Color.primary)
.cornerRadius(5)
.opacity(self.isShowing ? 1 : 0)
}
}
}
}
This is my DataStore. It is declared as ObservableObject
and has more than one @Published
property. Also it does some remote fetching from an API:
class CharacterStore: ObservableObject {
@Published private(set) var isLoading = false
// Fetches some stuff from a remote api
func fetch() {
self.isLoading = true
myService.getCharacters { (result) in
DispatchQueue.main.async {
self.isLoading = false
}
}
}
}
And finally this is the View I want to show my LoadingView
with the content of ContentView
in it. Of course I am setting the @EnvironmentObject
before showing this view.
struct ContentView: View {
@EnvironmentObject var charStore: CharacterStore
var body: some View {
LoadingView(isShowing: self.$charStore.isLoading) { // Here I get the error
// Show some Content here
Text("")
}
}
}
The problem is that I want to bind self.$charStore.isLoading
to LoadingView
. In this line i get the following error:
Generic parameter 'Subject' could not be inferred
I tried in several ways but none of these things work. Btw: If I use a @State
property in ContentView
it just works fine like this:
struct ContentView: View {
@EnvironmentObject var charStore: CharacterStore
@State var loads: Bool = false
var body: some View {
LoadingView(isShowing: self.$loads) { // Here I get no error
// Show some Content here
Text("")
}
}
}
Am I missing a thing? If you need further informations let me know i can provide more content if needed.
Thanks for the help!
Since your LoadingView
is not going to modify .isLoading, you do not need to pass it as a binding:
LoadingView(isShowing: self.$charStore.isLoading)
Instead, remove the @Binding
in LoadingView
:
struct LoadingView<Content>: View where Content: View {
var isShowing: Bool
...
and create it like this (remove the dollar sign):
LoadingView(isShowing: self.charStore.isLoading) { ... }
On the contrary, if you insist on passing a binding, then you need to remove the private(set)
from:
@Published private(set) var isLoading = false