kartbnb
kartbnb

Reputation: 53

SwiftUI Custom View repeat forever animation show as unexpected

I created a custom LoadingView as a Indicator for loading objects from internet. When add it to NavigationView, it shows like this enter image description here

I only want it showing in the middle of screen rather than move from top left corner

Here is my Code

struct LoadingView: View {
    @State private var isLoading = false
    var body: some View {
        Circle()
            .trim(from: 0, to: 0.8)
            .stroke(Color.primaryDota, lineWidth: 5)
            .frame(width: 30, height: 30)
            .rotationEffect(Angle(degrees: isLoading ? 360 : 0))
            .onAppear {
                withAnimation(.linear(duration: 1).repeatForever(autoreverses: false)) {
                    self.isLoading.toggle()
                }
            }
            
    }
}

and my content view

struct ContentView: View {
    var body: some View {
        NavigationView {
            LoadingView()
                .frame(width: 30, height: 30)
        }
    }
}

Upvotes: 3

Views: 880

Answers (2)

swiftPunk
swiftPunk

Reputation: 1

This is a bug from NavigationView, I tried to kill all possible animation but NavigationView ignored all my try, NavigationView add an internal animation to children! here all we can do right now!

struct ContentView: View {
    var body: some View {
        NavigationView {
            LoadingView()
        }
        
    }
}


struct LoadingView: View {
    
    @State private var isLoading: Bool = Bool()
    
    var body: some View {
        
        Circle()
            .trim(from: 0, to: 0.8)
            .stroke(Color.blue, lineWidth: 5.0)
            .frame(width: 30, height: 30)
            .rotationEffect(Angle(degrees: isLoading ? 360 : 0))
            .animation(Animation.linear(duration: 1).repeatForever(autoreverses: false), value: isLoading)
            .onAppear { DispatchQueue.main.async { isLoading.toggle() } }
 
    }
    
}

Upvotes: 2

Phil Dukhov
Phil Dukhov

Reputation: 87645

This looks like a bug of NavigationView: without it animation works totally fine. And it wan't fixed in iOS15.

Working solution is waiting one layout cycle using DispatchQueue.main.async before string animation:

struct LoadingView: View {
    @State private var isLoading = false
    var body: some View {
        Circle()
            .trim(from: 0, to: 0.8)
            .stroke(Color.red, lineWidth: 5)
            .frame(width: 30, height: 30)
            .rotationEffect(Angle(degrees: isLoading ? 360 : 0))
            .onAppear {
                DispatchQueue.main.async {
                    withAnimation(.linear(duration: 1).repeatForever(autoreverses: false)) {
                        self.isLoading.toggle()
                    }
                }
            }
    }
}

Upvotes: 3

Related Questions