iosswiftuiwatchosswiftui-tabview

SwiftUI animation when nested in a TabView stop working


I have a simple SwiftUI view like this, where the animation is performed correctly:

struct DemoView: View {
    @State private var isAnimating = false
    
    var body: some View {
        Text("Hello")
            .rotationEffect(.degrees(isAnimating ? 360 : 0))
            .animation(.smooth.repeatForever(), value: isAnimating)
            .onAppear(perform: {
                isAnimating = true
            })
    }
}

But as soon as I wrapped its content or embedded it into a TabView the animation stop working (not performed):

struct DemoView: View {
    @State private var isAnimating = false
    
    var body: some View {
        TabView {
            Text("Hello")
                .rotationEffect(.degrees(isAnimating ? 360 : 0))
                .animation(.smooth.repeatForever(), value: isAnimating)
                .onAppear(perform: {
                    isAnimating = true
                })
        }
    }
}

Note: I'm testing this on a WatchOS project.


Solution

  • For some reason when testing on a watch simulator, the animation is not performed. But I noticed that using an explicit animation works, it feels that this is a bug in SwiftUI.

    struct DemoView: View {
        @State private var isAnimating = false
            
        var body: some View {
            TabView {
                Text("Hello")
                    .rotationEffect(.degrees(isAnimating ? 360 : 0))
                    .onAppear(perform: {
                        withAnimation(.smooth.repeatForever()) {
                            isAnimating = true
                        }
                    })
            }
        }
    }
    

    Note: My UI and data observable is more complex than this, but the same approach works.