Skip to content

Instantly share code, notes, and snippets.

@JadenGeller
Last active July 4, 2020 23:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JadenGeller/cdaaf849e6dbab13cf82ab3c8ab2f6ea to your computer and use it in GitHub Desktop.
Save JadenGeller/cdaaf849e6dbab13cf82ab3c8ab2f6ea to your computer and use it in GitHub Desktop.
TemporaryStateBinding
@propertyWrapper
struct TemporaryState<Value>: DynamicProperty {
@State var modifiedValue: Value? = nil
let currentValue: Value
init(_ value: Value) {
self.currentValue = value
}
var wrappedValue: Value {
modifiedValue ?? currentValue
}
var projectedValue: Binding<Value> {
Binding(get: { wrappedValue }, set: { modifiedValue = $0 })
}
var isModified: Bool {
modifiedValue != nil
}
func discard() {
modifiedValue = nil
}
}
@propertyWrapper
struct TemporaryStateBinding<Value>: DynamicProperty {
@State var modifiedValue: Value? = nil
@Binding var currentValue: Value
init(_ value: Binding<Value>) {
self._currentValue = value
}
var wrappedValue: Value {
modifiedValue ?? currentValue
}
var projectedValue: Binding<Value> {
Binding(get: { wrappedValue }, set: { modifiedValue = $0 })
}
var isModified: Bool {
modifiedValue != nil
}
func discard() {
modifiedValue = nil
}
func save() {
if let value = modifiedValue {
currentValue = value
modifiedValue = nil
}
}
}
struct CountStepper: View {
@TemporaryStateBinding var count: Int
init(count: Binding<Int>) {
self._count = TemporaryStateBinding(count)
}
var body: some View {
VStack {
Stepper("Count: \(count)", value: $count)
Button("Save", action: _count.save)
Button("Cancel", action: _count.discard)
}
}
}
struct ContentView: View {
@State var count: Int = 0
var body: some View {
VStack {
CountStepper(count: $count)
Spacer().frame(height: 50)
Text("Saved Count: \(count)")
Button("Reset", action: { count = 0 })
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment