SwiftUI:无法推断通用参数“主题”

Tee*_*etz 7 swift swift5 swiftui combine

LoadingView使用SwiftUI 构建了一个用于在我从API提取远程数据时在应用程序中显示一些加载内容的功能。我正在使用Xcode 11.0 beta 5。

这是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)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的数据存储。它被声明为ObservableObject具有多个@Published属性。它还从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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,这是我要显示的视图LoadingView及其内容ContentView。当然,@EnvironmentObject在显示此视图之前,请先设置。

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("")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我想绑定self.$charStore.isLoadingLoadingView。在这一行中,我得到以下错误:

无法推断通用参数“主题”

我尝试了几种方法,但是这些都不起作用。顺便说一句:如果我@StateContentView其中使用属性,则可以像这样正常工作:

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("")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想念什么吗?如果您需要更多信息,请告诉我,如果需要,我可以提供更多内容。

谢谢您的帮助!

kon*_*iki 14

由于您LoadingView不会修改 .isLoading,因此您无需将其作为绑定传递:

LoadingView(isShowing: self.$charStore.isLoading)
Run Code Online (Sandbox Code Playgroud)

相反,删除@Bindingin LoadingView

struct LoadingView<Content>: View where Content: View {

    var isShowing: Bool
    ...
Run Code Online (Sandbox Code Playgroud)

并像这样创建它(删除美元符号):

LoadingView(isShowing: self.charStore.isLoading) { ... }
Run Code Online (Sandbox Code Playgroud)

相反,如果你坚持传递一个绑定,那么你需要删除private(set)from:

@Published private(set) var isLoading = false
Run Code Online (Sandbox Code Playgroud)

  • 对于未来遇到这种情况的 Google 员工来说,“Binding”需要能够访问投影属性的 setter 和 getter。我遇到了这个问题,我试图将计算属性(仅获取)映射到“Binding”参数,如下所示。这可以解决,但事实证明我的计算属性无论如何都需要一个设置器。添加一个解决了我的问题。 (3认同)