I have a SwiftUI iOS app with a “work time” screen.
On that screen, a circular ring with 60 tick marks rotates continuously while tracking is running. The app itself no longer crashes, but I still have one visual glitch:
- After the app is in background for a while and I return to foreground,
- the ring briefly moves a small step in the opposite direction once,
- then continues rotating normally clockwise.
No runtime error is shown, and this is a visual issue only.
Expected result: The ring should continue smoothly in the same direction after foreground resume, with no reverse step.
Actual result: One short reverse “tick” appears right after foreground resume, then normal rotation resumes.
I tested several approaches and the reverse step still happens:
withAnimation(.linear(...).repeatForever)+ restart on foreground.- Timeline-based rotation using
TimelineViewwith both.animationand.periodicschedules. - Rotation angle with and without modulo wrapping.
- Rotation from wall-clock time and from monotonic uptime.
- Rendering tweaks (Canvas rotation in geometry vs
rotationEffect, with/without warmup delays). - Different ring visuals (uniform ticks vs long/short hour-like ticks).
The issue is still reproducible.
import SwiftUI
struct ReproClockView: View {
@Environment(\.scenePhase) private var scenePhase
private let tickCount = 60
private let rotationDuration: Double = 120
@State private var rotationDegrees: Double = 0
@State private var hasAppeared = false
var body: some View {
ZStack {
Canvas { context, size in
let center = CGPoint(x: size.width / 2, y: size.height / 2)
let radius = min(size.width, size.height) / 2 - 8
for index in 0..
What is the correct SwiftUI approach to implement a continuously rotating ring that remains direction-stable across background/foreground transitions (no one-frame reverse step)?
If possible, please suggest a pattern that is robust on current iOS versions and avoids visual artifacts when scene phase changes.