Generic parameter could not be inferred, but only if I call a function

I have the following SwiftUI view that fails to compile with the error "Generic parameter 'Content' could not be inferred" but if I comment out the line context.doSomething() then it compiles and runs fine. It also works if I remove the Context class and just pass a Binding<Bool> into the closure directly.

What should I be doing to make it work, and why is the context.doSomething() line stopping the compiler from inferring what the Content parameter is?

public struct BrokenView<Content: View>: View {

    @ViewBuilder var content: (_ context: Context) -> Content

    public class Context: ObservableObject {
        @Published var context: Bool = false

        func doSomething() {
            context.toggle()
        }
    }

    @State var context = Context()

    public init(@ViewBuilder content: @escaping (_ context: Context) -> Content) {
        self.content = content
    }

    public var body: some View {
        VStack {
            content(context)
                .padding()
        }
    }
}

#Preview {
    BrokenView { context in // Error here
        Text("Hello")
        Button(action: {
            context.doSomething() // Comment out to fix
        }) {
            Text("Goodbye")
        }
    }
}
Answered by Claude31 in 770492022

Context is not known outside BrokenView.

I moved it out to make it compile.

import SwiftUI

public class Context: ObservableObject {
    @Published var context: Bool = false

    func doSomething() {
        context.toggle()
    }
}

public struct BrokenView<Content: View>: View {

    @ViewBuilder var content: (_ context: Context) -> Content

//    public class Context: ObservableObject {
//        @Published var context: Bool = false
//
//        func doSomething() {
//            context.toggle()
//        }
//    }

    @State var context = Context()

    public init(@ViewBuilder content: @escaping (_ context: Context) -> Content) {
        self.content = content
    }

    public var body: some View {
        VStack {
            content(context)
                .padding()
        }
    }
}

#Preview {
    BrokenView { context in // Error here
        Text("Hello")
        Button(action: {
            context.doSomething() // Comment out to fix
        }) {
            Text("Goodbye")
        }
    }
}
Accepted Answer

Context is not known outside BrokenView.

I moved it out to make it compile.

import SwiftUI

public class Context: ObservableObject {
    @Published var context: Bool = false

    func doSomething() {
        context.toggle()
    }
}

public struct BrokenView<Content: View>: View {

    @ViewBuilder var content: (_ context: Context) -> Content

//    public class Context: ObservableObject {
//        @Published var context: Bool = false
//
//        func doSomething() {
//            context.toggle()
//        }
//    }

    @State var context = Context()

    public init(@ViewBuilder content: @escaping (_ context: Context) -> Content) {
        self.content = content
    }

    public var body: some View {
        VStack {
            content(context)
                .padding()
        }
    }
}

#Preview {
    BrokenView { context in // Error here
        Text("Hello")
        Button(action: {
            context.doSomething() // Comment out to fix
        }) {
            Text("Goodbye")
        }
    }
}

Ah, of course. The full name of Context was BrokenView<Something>.Context and in the place it was being used in the Preview it couldn't work out what the generic Something was.

Thank you. I was bashing my head against it for ages

Generic parameter could not be inferred, but only if I call a function
 
 
Q