Skip to content

Instantly share code, notes, and snippets.

@timothycosta
Created April 10, 2020 04:43
Show Gist options
  • Save timothycosta/4270bd9ebfcde1a151572c61da11e2e8 to your computer and use it in GitHub Desktop.
Save timothycosta/4270bd9ebfcde1a151572c61da11e2e8 to your computer and use it in GitHub Desktop.
Replacement for didSet when using SwiftUI
/// TrackedValue is a property wrapper that allows you to work around the
/// lack of didSet when working with SwiftUI.
/// Explanation and example usage at: https://stackoverflow.com/a/60145397/467209
@propertyWrapper
struct TrackedValue<Tracked, Value>: DynamicProperty {
var trackedHolder: State<ValueHolder<Tracked>>
var valueHolder: State<ValueHolder<Value>>
init(wrappedValue value: Value, tracked: Tracked) {
self.trackedHolder = State(initialValue: ValueHolder(tracked))
self.valueHolder = State(initialValue: ValueHolder(value))
}
var wrappedValue: Value {
get { self.valueHolder.wrappedValue.value }
nonmutating set { self.valueHolder.wrappedValue = ValueHolder(newValue) }
}
var projectedValue: Self { return self }
@discardableResult
public func update(tracked: Tracked, with block:(Tracked, Value) -> Value) -> EmptyView {
self.valueHolder.wrappedValue.value = block(self.trackedHolder.wrappedValue.value, self.valueHolder.wrappedValue.value)
self.trackedHolder.wrappedValue.value = tracked
return EmptyView()
}
}
class ValueHolder<Value> {
init(_ value: Value) { self.value = value }
var value: Value
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment