1

I have a very simple spinner animation on a page.

struct SmallSpinner: View {
    @State private var spinXSmall = false
    var body: some View {
        Circle() // X-Small
            .trim(from: 1 / 4, to: 1)
            .stroke(style: StrokeStyle(lineWidth: 1, lineCap: .round, lineJoin: .round))
            .foregroundColor(Color(#colorLiteral(red: 0.6588235294, green: 0.6588235294, blue: 0.6745098039, alpha: 1)))
            .frame(width: 12, height: 12)
            .rotationEffect(.degrees(spinXSmall ? 0 : 360))
            .scaleEffect(spinXSmall ? 1 : 0.8)
            .animation(Animation.easeOut(duration: 1).repeatForever(autoreverses: false))
            .onAppear {
                self.spinXSmall.toggle()
            }
    }
}

It looks strange and i don't know what's the root cause. see video below.

enter image description here

George
  • 25,988
  • 10
  • 79
  • 133
LiangWang
  • 8,038
  • 8
  • 41
  • 54
  • Make sure to pass in a ‘value’ for the ‘.animation’. Otherwise SwiftUI will animate it whenever the layout changes, causing weird position animations. – aheze Aug 31 '21 at 22:27
  • It is because of NavigationView! And there is no easy answer for it, I must see the all code, then maybe I can answer it! but the issue is not animation, I believe you have NavigationView, right? – ios coder Aug 31 '21 at 23:13
  • @swiftPunk You are right, the problem is on NavigationView. Everything is perfect if i remove NavigationView. However, i do need that, is there any workaround? Thank – LiangWang Aug 31 '21 at 23:32
  • @LiangWang I recently answered a very similar question [here](https://stackoverflow.com/questions/68659667/swiftui-unexpected-animation-when-using-a-non-state-var/68660932#68660932) - try using explicit `withAnimation` instead. And you might need to also [use `DispatchQueue.main.async {}`](https://stackoverflow.com/a/64566746/14351818), for mysterious reasons only known to Apple. – aheze Aug 31 '21 at 23:39
  • @LiangWang: I answered almost same question here: https://stackoverflow.com/a/68906529/14998134 but the issue could be deferent in your case, I must look to your code for better answer. – ios coder Aug 31 '21 at 23:45
  • What is the behavior that you don't like? The animation is doing exactly what you programmed it to do. – Yrb Sep 01 '21 at 01:30

1 Answers1

2

the issue happens due to an issue in NavigationView and it's not solved yet, so what you need to do is to add the toggle for spinXSmall in DispatchQueue and add a value to the animation Modifier and give it the spinXSmall

struct SmallSpinner: View {
@State private var spinXSmall = false
var body: some View {
    Circle() // X-Small
        .trim(from: 1 / 4, to: 1)
        .stroke(style: StrokeStyle(lineWidth: 1, lineCap: .round, lineJoin: .round))
        .foregroundColor(Color(#colorLiteral(red: 0.6588235294, green: 0.6588235294, blue: 0.6745098039, alpha: 1)))
        .frame(width: 12, height: 12)
        .rotationEffect(.degrees(spinXSmall ? 0 : 360))
        .scaleEffect(spinXSmall ? 1 : 0.8)
        .animation(Animation.easeOut(duration: 1).repeatForever(autoreverses: false),value:spinXSmall)
        .onAppear {
            DispatchQueue.main.async {
            self.spinXSmall.toggle()
        }
        }
   }
   }
belal medhat
  • 462
  • 1
  • 4
  • 18