Skip to content

Instantly share code, notes, and snippets.

@Amzd
Last active September 20, 2023 05:27
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Amzd/c3015c7e938076fc1e39319403c62950 to your computer and use it in GitHub Desktop.
Save Amzd/c3015c7e938076fc1e39319403c62950 to your computer and use it in GitHub Desktop.
SwiftUI Binding wrappers for willSet and didSet
extension Binding {
/// Wrapper to listen to didSet of Binding
func didSet(_ didSet: @escaping ((newValue: Value, oldValue: Value)) -> Void) -> Binding<Value> {
return .init(get: { self.wrappedValue }, set: { newValue in
let oldValue = self.wrappedValue
self.wrappedValue = newValue
didSet((newValue, oldValue))
})
}
/// Wrapper to listen to willSet of Binding
func willSet(_ willSet: @escaping ((newValue: Value, oldValue: Value)) -> Void) -> Binding<Value> {
return .init(get: { self.wrappedValue }, set: { newValue in
willSet((newValue, self.wrappedValue))
self.wrappedValue = newValue
})
}
}
struct FilterView: View {
@Binding var filters: [String]
@Binding var selectedFilters: Set<String>
var body: some View {
List(filters, id: \.self, selection: $selectedFilters.didSet {
print("Selection changed from \($1) to \($0)")
}, rowContent: { filter in
Text(filter)
})
}
}
@Amzd
Copy link
Author

Amzd commented Apr 20, 2021

I know what @discardableResult does. I don't really understand how you think your code would work, like how does the original binding know about your handler closure?..

I tested it because you were very confident, it doesn't work.

@ugommirikwe
Copy link

@Amzd my apologies. Yeah, using the extension function in the .onAppear() hook doesn't work, true. But it still works as in the original use case you provided: ...selection: $selectedFilters.onChange... In any case, the original intention was to offer a more concise version of the code as the one you created.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment