swiftviewmodifierswift-keypath

Swift - Pass a paremeter to a KeyPath


SwiftUI modifiers don't allow passing optional values, and I'd really like to handle them in a clean way. E.g.

struct MyView: View {
    let accessibilityValue: String?

    var body: some View {
        Text("Foo")
            .accessibilityValue(accessibilityValue)
    }
}

This won't work because accessibilityValue expects a non-Optional and I don't want to use accessibilityValue ?? "" because I'll lose the default accessibilityValue.

I want to call a function like

var body: some View {
    Text("Foo")
        .map(accessibilityValue, \.accessibilityValue)
}

When I try:

@ViewBuilder func map<T, Content: View>(_ value: T?,
                                        _ keyPath: KeyPath<Self, Content>) -> some View {
    if let value {
        self[keyPath: keyPath](value) // Error
    } else {
        self
    }
}

I get the error Cannot call value of non-function type 'Content'.

And when I try:

@ViewBuilder func map<T, Content: View>(_ value: T?,
                                        _ keyPath: KeyPath<Self, ((T) -> Content)>) -> some View {
    if let value {
        self[keyPath: keyPath](value)
    } else {
        self
    }
}

I get an error at the caller: Key path cannot refer to instance method 'accessibilityValue'.

Could I create a KeyPath to a KeyPath? That doesn't seem to make sense and I couldn't see how it's done. Any help would be appreciated.


Solution

  • As mentioned in comments, it seems that there's no answer here. KeyPath cannot any parameters.