swift - 我可以在 SwiftUI 的状态变量中使用泛型类型吗?
问题描述
有没有办法在 Swift 的状态变量中使用泛型类型?
我有一个显示 3 个按钮的视图。每个按钮加载一个或类型的项目数组,MyGenericObject<TypeA>
目的是然后显示所选数组中的对象列表。MyGenericObject<TypeB>
MyGenericObject<TypeC>
但是当我写的时候 XCode 会抛出一个错误@State var objects: [MyGenericObject<T>]?
即使使用单个对象而不是数组,也会出现错误,如下例所示:
struct ObjectView: View {
// I would like the following to be @State var object: MyGenericObject<T> instead...
@State var object: MyGenericObject<TypeA>?
var body: some View {
Text("\(object?.data.name)")
// because I would then like to do something like this, if possible:
if type(of: object) == MyGenericObject<TypeA> {
...show list of item of this type
} else
if type(of: object) == MyGenericObject<TypeB> {
...show list of item of this type
}
else {
...show list of item of type MyGenericObject<TypeC>
}
// or better yet, use a switch
}
如何在 SwiftUI 的 @State 变量中使用泛型类型?有没有更好的方法来实现我想要的?
解决方案
我偶然发现了这个问题,并查看了要点。很难判断这是否正是您想要的,但似乎它可能会让您走上正确的道路:
protocol InstrumentType {
var name : String { get set }
var int : Int { get set }
var bool : Bool { get set }
}
class Instrument<T : InstrumentType>: ObservableObject {
@Published var object: T
init(object: T){
self.object = object
}
}
class Trumpet: NSObject, ObservableObject, InstrumentType {
@Published var name: String
@Published var int: Int
@Published var bool: Bool
init(name: String = "newTrumpet", int: Int = 1, bool: Bool = true){
self.name = name
self.int = int
self.bool = bool
}
}
class Guitar: NSObject, ObservableObject, InstrumentType {
@Published var name: String
@Published var int: Int
@Published var bool: Bool
init(name: String = "newGuitar", int: Int = 2, bool: Bool = true){
self.name = name
self.int = int
self.bool = bool
}
}
class Clarinet: NSObject, ObservableObject, InstrumentType {
@Published var name: String
@Published var int: Int
@Published var bool: Bool
init(name: String = "newClarinet", int: Int = 3, bool: Bool = true){
self.name = name
self.int = int
self.bool = bool
}
}
struct ContentView : View {
var body: some View {
_ContentView(instrument: Instrument(object: Trumpet(name: "testTrumpet")))
}
}
//VIEWS
struct _ContentView<T : InstrumentType>: View {
@StateObject var instrument: Instrument<T>
var body: some View {
InstrumentView(instrument: instrument)
.environmentObject(instrument)
.frame(width: 300, height: 100)
}
}
struct InstrumentView<T : InstrumentType>: View {
@ObservedObject var instrument: Instrument<T>
var body: some View {
VStack {
if type(of: instrument) == Instrument<Trumpet>.self {
Text("Instrument is a trumpet")
Text("\(instrument.object.name)")
Text("\(instrument.object.int)")
Text("\(instrument.object.bool ? "true" : "false")")
} else
if type(of: instrument) == Instrument<Guitar>.self {
Text("Instrument is a guitar")
Text("\(instrument.object.name)")
Text("\(instrument.object.int)")
}
else {
Text("Instrument is a clarinet")
}
Button("Update int") {
instrument.object.int += 1
}
}
}
}
添加了一个协议,该协议
InstrumentType
定义了每台仪器上的可用属性——这让我可以摆脱Metadata
,因为无论如何它都存储在每台仪器上将每个泛型限制为
InstrumentType
对于每种类型的仪器,我都感到有些困惑
@StateObject
——我假设我所做的可能就是您正在寻找的(一个通用的@StateObject,但也许这就是答案与意图不同的地方)我能够以您希望的方式
environmentObject
使用object.name
添加了一个 Button 以显示 @Published 属性正确传播。
推荐阅读
- python - 框架对象没有属性
- c# - 存储过程与简单 SQL 性能比较
- python - 了解序列化程序的作用以及它们的作用以及在基于类的视图的情况下我可以在哪里记录我的请求
- protocol-buffers - Protobuf,从 protoc 插件获取自定义扩展值
- python - 如何使用python将字符串时间戳转换为UTC和本地数据帧?
- excel - excel中的单元格保护问题
- java - 如何从 firebase 实时数据库中获取特定值。类似于 sql 中的 where 子句
- c - 长时间运行的程序中的 sizeof vs strlen
- python - 线程不解冻 Tkinter
- angular - 如何动态添加一个类?