I'm working on a Swift package where an option will be to pass in a generic type (Person
) and then that GenericStruct
can use properties on that type passed in. The issue obviously is that the generic T
has no idea what's being passed in. Is there a way to define the property to access on the generic type T
?
struct Person: Equatable {
var name: String
var height: Double
}
struct ContentView: View {
@State private var james = Person(name: "James", height: 175.0)
var body: some View {
GenericStruct(person: $james)
}
}
struct GenericStruct<T: Equatable>: View {
@Binding var person: T
var body: some View {
Text(person.name)) // This line.
}
}
I want to specifically pass in which property to access on Person
when passing it to GenericStruct
. The property won't always be name
it could be anything I define within Person
. For example:
GenericStruct(person: $james, use: Person.name)
CodePudding user response:
Isn't this exactly a protocol?
protocol NameProviding {
var name: String { get }
}
struct GenericStruct<T: Equatable & NameProviding>: View { ... }
Or is there a more subtle part of the question?
The best way to do this is to pass a String Binding:
struct GenericStruct: View {
@Binding var text: String
var body: some View {
Text(text)) // This line.
}
}
GenericStruct(text: $james.name)
But it is possible with key paths. It's just a bit more awkward and less flexible in this particular case:
// Should be the syntax, but I haven't double-checked it.
struct GenericStruct<T: Equatable>: View {
@Binding var person: T
var use: KeyPath<T, String>
var body: some View {
Text(person[keyPath: use]))
}
}
GenericStruct(person: $james, use: \.name)