Reputation: 2529
I'm trying to emmit values from a SwiftUI component. I wan't to have an API like DragGesture
(as an example).
DragGesture()
.onChanged { value in
print("Get access to value when it changes \(value)")
}
How can I add a callback function like that to MyCustomComponent
? I would prefer to have the exact same syntax. The component will emit values continously (based on a DragGesture locally inside the component. Code for the Component I wan't to augment can be seen here.
Upvotes: 2
Views: 2635
Reputation: 2529
Found this answer by @Asperi, which shows how to do it like I wanted. The trick is to actually return a copy of itself.
typealias OnChange = ((CGFloat) -> Void)?
struct WheelView: View {
var action: OnChange
func onChanged(perform action: OnChange) -> Self {
var copy = self
copy.action = action
return copy
}
var body: some View {
Circle()
.gesture(DragGesture()
.onChanged { value in
// 📣 Emit the angle change
if let action = self.action {
action(0.4)
}
})
}
}
Then we can use our component like this:
struct Usage: View {
var body: some View {
WheelView()
.onChanged { value in
print("Value is \(value)")
}
}
}
Upvotes: 3
Reputation: 258355
Here is one of possible approaches (simplest IMO) ...
struct WheelView: View {
var onEmit: (CGFloat) -> Void
init(onEmit: @escaping (CGFloat)-> Void = {_ in }) {
self.onEmit = onEmit
}
...
// TODO: Emit angle from here
self.onEmit(self.angle)
}
usage (in any place of ViewBuilder
)
WheelView() { angle in
print("\(angle)")
}
Upvotes: 3