In SwiftUI, for this code to toggle the display of view:
@State var show = true
Button { withAnimation { show.toggle() }}
label: { Image(systemName: show ? "chevron.down" : "chevron.right") }
if show { ... }
The animation will be shown if the show is the @State variable.
However, I found that if show is changed to @AppStorage (so to keep the show state), the animation will not be shown.
Is there a way to keep the show state and also preserve the animation?
You can also replace the withAnimation {}
with the .animation(<#T##animation: Animation?##Animation?#>, value: <#T##Equatable#>)
modifier and then it seems to work directly with the @AppStorage wrapped variable.
import SwiftUI
struct ContentView: View {
@AppStorage("show") var show: Bool = true
var body: some View {
VStack {
Button {
self.show.toggle()
}
label: {
Rectangle()
.fill(Color.red)
.frame(width: self.show ? 200 : 400, height: 200)
.animation(.easeIn, value: self.show)
}
Rectangle()
.fill(Color.red)
.frame(width: self.show ? 200 : 400, height: 200)
.animation(.easeIn, value: self.show)
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
EDIT: Following the comments, another solution
import SwiftUI
struct ContentView: View {
@State private var show: Bool
init() {
self.show = UserDefaults.standard.bool(forKey: "show")
// Or self._show = State(initialValue: UserDefaults.standard.bool(forKey: "show"))
}
var body: some View {
VStack {
Button {
withAnimation {
self.show.toggle()
}
}
label: {
Text("Toggle")
}
if show {
Rectangle()
.fill(Color.red)
.frame(width: 200 , height: 200)
}
}
.padding()
.onChange(of: self.show) { newValue in
UserDefaults.standard.set(newValue, forKey: "show")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With