Created
June 1, 2021 09:38
-
-
Save vibrazy/3f1b15a38ca74763bd3e411eea8447c4 to your computer and use it in GitHub Desktop.
Making it easier to deal with animations in SwiftUI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@propertyWrapper | |
struct AnimatedState<Value> : DynamicProperty { | |
let storage: State<Value> | |
let animation: Animation? | |
init( | |
value: Value, | |
animation: Animation? = nil | |
) { | |
self.storage = State<Value>(initialValue: value) | |
self.animation = animation | |
} | |
public var wrappedValue: Value { | |
get { | |
storage.wrappedValue | |
} | |
nonmutating set { | |
self.process(newValue) | |
} | |
} | |
public var projectedValue: Binding<Value> { | |
storage.projectedValue | |
} | |
private func process(_ value: Value) { | |
withAnimation(animation) { | |
self.storage.wrappedValue = value | |
} | |
} | |
} | |
struct AnimatedStateExample: View { | |
@AnimatedState( | |
value: false, | |
animation: .spring() | |
) var scaleSquare | |
@AnimatedState( | |
value: false, | |
animation: .spring().speed(0.5) | |
) var scaleSquare2 | |
var body: some View { | |
VStack(spacing: 150) { | |
Rectangle() | |
.fill(Color.red) | |
.frame(width: 100, height: 100) | |
.scaleEffect(scaleSquare ? 2 : 1) | |
Rectangle() | |
.fill(Color.blue) | |
.frame(width: 100, height: 100) | |
.scaleEffect(scaleSquare2 ? 2 : 1) | |
} | |
.onAppear { | |
scaleSquare.toggle() | |
scaleSquare2.toggle() | |
} | |
} | |
} | |
struct AnimatedStateExample_Previews: PreviewProvider { | |
static var previews: some View { | |
AnimatedStateExample() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How can I bind this animatedState property to another view, to maintain single source of truth among multiple views?