For some reason the SwiftUi withAnimation does not work in the navigationBarItems modifier. Is there a fix for that? I know the .animation modifier on the view that is animated works but this is not enough for more complex animations.
I was wondering that no one asked this question before, I assume more people have the issue. Does anyone know a fix for that?
One example here: https://drive.google.com/file/d/1d2Ud2xxhVCJBCfBQwlZ1mJgTnyNpxc_-/view?usp=sharing
struct TestView: View {
@State var red = true
var body: some View {
NavigationView {
VStack {
HStack {
Rectangle()
.fill(red ? Color.red : .blue)
.onTapGesture {
withAnimation(Animation.easeIn(duration: 1), {
red.toggle()
})
}
}
Spacer()
}
.navigationTitle("Test")
.navigationBarItems(leading:
HStack {
Rectangle()
.fill(red ? Color.red : .blue)
.onTapGesture {
withAnimation(Animation.easeIn(duration: 1), {
red.toggle()
})
}
}
)
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
```
Edit: Aspires solution is valid for my original question. For some reason it still does not work in the context I am using it in:
struct ContentView: View {
@State var redColor = false
var body: some View {
NavigationView {
Button("change Color", action: {
withAnimation(Animation.easeIn(duration: 1), {
redColor.toggle()
})
})
.navigationTitle("Test")
.navigationBarItems(leading:
RectView(redColor: $redColor)
)
}
}
}
struct RectView: View {
@State var red: Bool = false
@Binding var redColor: Bool
var body: some View {
HStack {
Rectangle()
.fill(red ? Color.red : .blue)
}.onChange(of: redColor, perform: { _ in
red.toggle()
})
}
}
A possible solution is to separate that state dependent animatable code into standalone view, like show below.
Tested with Xcode 12.4 / iOS 14.4
struct TestBarAnimationView: View {
@State var red = true
var body: some View {
NavigationView {
VStack {
RectView(red: $red) // << here !!
Spacer()
}
.navigationTitle("Test")
.navigationBarItems(leading:
RectView(red: $red) // << here !!
)
}
}
}
struct RectView: View {
@Binding var red: Bool
var body: some View {
HStack {
Rectangle()
.fill(red ? Color.red : .blue)
.onTapGesture {
withAnimation(Animation.easeIn(duration: 1), {
red.toggle()
})
}
}
}
}