Two circles on Zstack is not align if view is render on NavigationView.
struct SpinnerView: View {
@State private var isLoading = false
var body: some View {
NavigationView {
ZStack {
Circle()
.stroke(Color(.systemGray5), lineWidth: 7)
.frame(width: 64, height: 64)
Circle()
.trim(from: 0, to: 0.2)
.stroke(Color.green, lineWidth: 7)
.frame(width: 64, height: 64)
.rotationEffect(Angle(degrees: isLoading ? 360 : 0))
.animation(Animation.linear(duration: 1).repeatForever(autoreverses: false))
.onAppear() {
self.isLoading = true
}
}
}
}
}
In order to reproduce your problem, I moved NavigationView
to a start screen ContentView
and launch SpinnerView
with a NavigationLink
. Once I do that, I can see the falling animation.
If you turn the animation into an explicit animation triggered by withAnimation()
, and delay it until the view loads, you can avoid the extra movement introduced by the NavigationView
. By changing isLoading
to true
initially, and then setting it to false
in onAppear
before calling withAnimation
, the false
state which occurs after the view is loaded will be established (for the purposes of the animation) as the before state. Then, when isLoading
is set to true
in the withAnimation
block, the animation will proceed. This avoids including the movement caused by imbedding the screen in a navigation screen because this all happens before isLoading
is set to false
.
struct SpinnerView: View {
@State private var isLoading = true
var body: some View {
ZStack {
Circle()
.stroke(Color(.systemGray5), lineWidth: 7)
.frame(width: 64, height: 64)
Circle()
.trim(from: 0, to: 0.2)
.stroke(Color.green, lineWidth: 7)
.frame(width: 64, height: 64)
.rotationEffect(Angle(degrees: isLoading ? 360 : 0))
.onAppear() {
self.isLoading = false
withAnimation(.linear(duration: 1).repeatForever(autoreverses: false)) {
self.isLoading = true
}
}
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink("Go to spinner view", destination: SpinnerView())
}
}
}
Here is it running in the simulator: