3

I am relatively new to SwiftUI and I am trying to implement animated loader to my app. It works fine until I scroll my content inside scroll view down and then move back to trigger pull to refresh. Circles started to jump though they should only increase and decrease their size one by one.

My code is

struct ActivityIndicator: View {

    var isShowing: Bool
    @State private var shouldAnimate = false

    init(isShowing: Bool) {
        self.isShowing = isShowing
    }

    var body: some View {
        HStack(alignment: .center) {
            Circle()
                .fill(Color.mainAccent)
                .frame(width: 20, height: 20)
                .scaleEffect(shouldAnimate ? 1.0 : 0.5)
                .animation(Animation.easeInOut(duration: 0.5).repeatForever())
            Circle()
                .fill(Color.mainAccent)
                .frame(width: 20, height: 20)
                .scaleEffect(shouldAnimate ? 1.0 : 0.5)
                .animation(Animation.easeInOut(duration: 0.5).repeatForever().delay(0.3))
            Circle()
                .fill(Color.mainAccent)
                .frame(width: 20, height: 20)
                .scaleEffect(shouldAnimate ? 1.0 : 0.5)
                .animation(Animation.easeInOut(duration: 0.5).repeatForever().delay(0.6))
        }
            .opacity(self.isShowing ? 1 : 0)
            .onAppear {
                self.shouldAnimate = true
            }
    }
}

I have read few articles related to my case and it seems that I might had to use withAnimation (Explicit) instead .animation (Implicit) but I can't make it work properly.

Btw I connect my Activity Indicator to the scrollView using Loading View modifier and it looks like this

struct LoadingView: ViewModifier {
    @Binding var isShowing: Bool

    func body(content: Content) -> some View {
            ZStack(alignment: .center) {
                content
                    .disabled(self.isShowing)
                    .blur(radius: self.isShowing ? 3 : 0)

                ActivityIndicator(isShowing: isShowing)
            }
    }
}

Any ideas and suggestions are appreciated I am really stuck. Thanks

2 Answers 2

3

Try to link all your animations to related state, like

var body: some View {
    HStack(alignment: .center) {
        Circle()
            .fill(Color.mainAccent)
            .frame(width: 20, height: 20)
            .scaleEffect(shouldAnimate ? 1.0 : 0.5)
            .animation(Animation.easeInOut(duration: 0.5).repeatForever(), 
                       value: shouldAnimate)   // << here !!
Sign up to request clarification or add additional context in comments.

Comments

0

If you have any problems with the previous answer, try removing the .animation and replace it with withAnimation:

https://developer.apple.com/documentation/swiftui/withanimation(_:_:)

The advantage of that is that it does not affect other animations.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.