ios – Activity Indicator in SwiftUI cannot cover navigation bar


I have 2 views, lets name it view A and view B.
View B will be shown by pushed from view A.

In view B, I want to show Activity Indicator that cover the whole screen of the device.
But in my approach, it turns out that it only cover the view B content. The navigation bar is not covered with the Activity Indicator.

I used view modifier to show Activity Indicator.
Here’s the code:

struct ActivityIndicator: UIViewRepresentable {
    @Binding var isAnimating: Bool
    let style: UIActivityIndicatorView.Style

    func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView {
        return UIActivityIndicatorView(style: style)
    }

    func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>) {
        isAnimating ? uiView.startAnimating() : uiView.stopAnimating()
    }
}

struct ActivityIndicatorModifier: AnimatableModifier {
    var isLoading: Bool

    init(isLoading: Bool, color: Color = .primary, lineWidth: CGFloat = 3) {
        self.isLoading = isLoading
    }

    var animatableData: Bool {
        get { isLoading }
        set { isLoading = newValue }
    }

    func body(content: Content) -> some View {
        ZStack {
            if isLoading {
                GeometryReader { geometry in
                    ZStack(alignment: .center) {
                        content
                            .disabled(self.isLoading)
                            .blur(radius: self.isLoading ? 3 : 0)

                        VStack {
                            ActivityIndicator(isAnimating: .constant(true), style: .large)
                        }
                        .frame(width: geometry.size.width / 2,
                               height: geometry.size.height / 5)
                        .background(Color.secondary.colorInvert())
                        .foregroundColor(Color.primary)
                        .cornerRadius(20)
                        .opacity(self.isLoading ? 1 : 0)
                        .position(x: geometry.frame(in: .local).midX, y: geometry.frame(in: .local).midY)
                    }
                }
            } else {
                content
            }
        }
    }
}

And this is the code of view B:

    var body: some View {
        VStack {
            ** View Content **
        }
        .padding(.top)
        .toolbar(content: {
            ToolbarItemGroup(placement: .navigationBarTrailing) {
                Button {

                } label: {
                    Text("Save")
                        .font(.bold(.body)())
                }
                .padding(.trailing)
            }
        })
        .navigationTitle("View B")
        .background(Color.themeColor)
        .modifier(ActivityIndicatorModifier(isLoading: loadingState))
    }

This is the result when Activity Indicator is shown, the ‘Back’ button is still tappable:
ViewB

How to show Activity Indicator in correct way to cover the whole screen including the navigation bar?

Thank you in advance.

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img