Several buttons with no position animations on them will begin to move around when placed inside a NavigationStack. If you comment out the NavigationStack the buttons will remain still and only the desired glow animation will occur. Also this only seems to occur when the button animation toggles based on a @Published Bool, not with a @State Bool
NavigationStack usage adding unwanted position animation
That seems to be a result of:
animation(.easeInOut(duration: 1).repeatForever(autoreverses: true)
and not necessarily the Navigatio Stack. PulsingCircle1 animation sequence doesn't need to play in reverse after playing forward.
Instead, you could use a timer to trigger the animation every second.
@Observable
final class MuseViewModel {
var isScanning = false
private var timer: Timer?
func startScanning() {
timer?.invalidate()
guard !isScanning else { return }
isScanning = true
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
self.isScanning.toggle()
}
}
func stopScanning() {
timer?.invalidate()
timer = nil
isScanning = false
}
}
struct PulsingCircle1: View {
@Binding var isScanning: Bool
@State private var scale: CGFloat = 1.0
private var animation: Animation {
.easeInOut
.speed(0.1)
.repeatForever(autoreverses: false)
}
var body: some View {
ZStack {
Circle()
.fill(Color.blue.opacity(0.3))
.scaleEffect(scale)
.opacity(isScanning ? 0.7 : 0)
Circle()
.fill(Color.white)
.overlay(
Image(systemName: "1.circle")
.foregroundColor(.gray)
)
}
.frame(width: 44, height: 44)
.animation(.easeInOut(duration: 0.1), value: isScanning)
.onChange(of: isScanning) { oldState, newState in
print("PulsingCircle1: isScanning: \(newState)")
scale = newState ? 1.2 : 1.0
}
}
}
- The PulsingCircle1 animation sequence does need to play in reverse after playing forward because I'm trying to create a glow effect that fades in and out
- I'm try the sample code and I'm not seeing any animation, the blue ring is just blinking on and off.