SwiftUI泛型结构体的@ObservedObject定义报错求助
解决SwiftUI泛型结构体扩展ViewModel的实例化问题
问题根源
你遇到的错误是因为GenericViewModel是泛型结构体GenericView<T, U, V>的扩展类,它的实际类型是GenericView<T, U, V>.GenericViewModel——必须显式指定T、U、V的具体类型才能实例化。但你的场景里,ViewModel并不依赖GenericView的泛型参数,所以没必要把它放在扩展里。
推荐解决方案:将ViewModel改为独立类
把GenericViewModel从GenericView的扩展中移出,变成独立的ObservableObject类,这样就不需要绑定泛型参数,实例化会更简单,同时解耦ViewModel和View的泛型依赖。
修改后的GenericViewModel
import Foundation class GenericViewModel: ObservableObject { @Published var someData = "" // 修复原初始化方法的无效赋值问题 init() {} }
修改后的GenericView
将原本的@StateObject改为外部传入的@ObservedObject,让ViewModel可以从父视图注入:
import SwiftUI struct GenericView<T: Shape, U: Shape, V: View>: View { @ObservedObject var vm: 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) } }
修改后的ContentView
现在可以直接实例化GenericViewModel,不再需要处理泛型参数:
import SwiftUI struct ContentView: View { @ObservedObject var vm = 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() } } }
备选方案:保留扩展并显式指定泛型参数
如果必须把ViewModel留在GenericView扩展中,实例化时需要明确指定GenericView的泛型参数(对应你要创建的视图的形状和内容类型):
// 在ContentView中 @ObservedObject var vm = GenericView<Circle, Rectangle, Text>.GenericViewModel()
这种方式耦合性极高,一旦GenericView的参数类型变化,这里必须同步修改,仅适合ViewModel确实依赖GenericView泛型参数的场景。
内容的提问来源于stack exchange,提问作者user19537947
相关产品推荐
相关产品推荐

