Home > database >  Setting an @ObservedObject var that also relies on a struct with generics (Reference to generic type
Setting an @ObservedObject var that also relies on a struct with generics (Reference to generic type

Time:10-02

I'm learning about SwiftUI generics and I have having some issues when defining a @ObservedObject variable; itself an extension of a struct that has generic arguments. I'm getting the following error when setting:

@ObservedObject var vm = GenericView.GenericViewModel

Error:

Reference to generic type '_' requires arguments in <...>

Xcode is asking me to explicitly define my generics, but everything that I have tried so far has failed. What exactly is it that Xcode wants me to pass? Here is some sample code:

GenericView

import SwiftUI

struct GenericView<T: Shape, U: Shape, V: View>: View {
    @StateObject var vm = GenericView.GenericViewModel()
    
    let shape1:  T
    let shape2:  U
    let color1:  Color
    let color2:  Color
    let color3:  Color
    let content: () -> V
    
    var body: some View {
        ZStack {
            HStack {
                shape1
                    .foregroundColor(color1)
                shape2
                    .foregroundColor(color2)
            }
            .overlay(
                VStack {
                    content()
                    Text(vm.someData)
                }
                    .foregroundColor(color3)
            )
        }
        .frame(width:  200,
               height: 100)
    }
}

GenericViewModel

import Foundation

extension GenericView {
    class GenericViewModel: ObservableObject {
        @Published var someData = ""
        
        init() { self.someData = someData }
    }
}

ContentView

import SwiftUI

struct ContentView: View {
    @ObservedObject var vm = GenericView.GenericViewModel
    
    var body: some View {
        VStack {
            GenericView(vm:     vm,
                        shape1: Circle(),
                        shape2: Rectangle(),
                        color1: .black,
                        color2: .gray,
                        color3: .white) {
                           Text("Hello, world.")
                        }
            
            Button {
                vm.someData = "Hello back."
            } label: {
                Rectangle()
                    .overlay(
                        Text("Respond")
                            .foregroundColor(.black)
                            .bold()
                    )
                    .frame(width:  100,
                           height: 50)
            }
            .padding()
            
        }
    }
}

CodePudding user response:

The modifications to make it correct : Definition of GenericView

struct GenericView<T: Shape, U: Shape, V: View>: View {
    // This observed object : it does not belong to Generci view
    @ObservedObject var vm: GenericViewModel
...

Declaration of model :

struct ContentView: View {
    // The model belongs to content view
    // the model var must declare the type of the generic view
    @StateObject var vm = GenericView<Circle, Rectangle, Text>.GenericViewModel()
...
  • Related