0

I'm trying to show a ProgressView while something is being processed, and the app busy.

in this exemple during the for

import SwiftUI

struct ContentView: View {

@State var isLoading:Bool = false

var body: some View {
    ZStack{

            if self.isLoading {
                ProgressView()
                    .zIndex(1)
            }

        Button("New View"){
      
            self.isLoading = true
           
            var x = 0
            for a in 0...5000000{
                x += a
            }
            
            self.isLoading = false
      
            print("The End: \(x)")
        }
        .zIndex(0)
    }
}
}  

In my app the ProgressView don't appears when i Press the button

So how I can display the ProgressView while the for is running?

I'm using Xcode 12

GaF
  • 101
  • 2
  • 5
  • Does your code not work? What happens? – mginn Sep 06 '20 at 02:36
  • The code runs, but the ProgressView don’t appear – GaF Sep 06 '20 at 02:39
  • It's possible that the compiler optimizes the for loop so it's too fast. If you comment out the line setting `isLoading = false`, does the progress view appear? – mginn Sep 06 '20 at 02:44
  • Yes apear, but after the print – GaF Sep 06 '20 at 02:52
  • State changes are not instantaneous. It could be that the task you're using is just too fast. A better test might be `DispatchQueue.main.asyncAfter`. – mginn Sep 06 '20 at 04:24

1 Answers1

0

You just blocked UI thread with sync long button action. The solution is to make it in background.

Here is possible fix (tested with Xcode 12 / iOS 14):

struct ContentView: View {

    @State var isLoading:Bool = false

    var body: some View {
        ZStack{

            if self.isLoading {
                ProgressView()
                    .zIndex(1)
            }

            Button("New View"){
                self.isLoading = true

                DispatchQueue.global(qos: .background).async {
                    var x = 0
                    for a in 0...500000 {
                        x += a
                    }

                    DispatchQueue.main.async {
                        self.isLoading = false
                        print("The End: \(x)")
                    }
                }
            }
            .zIndex(0)
        }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • this, kinda works, but the app isn't busy during the for, and I need the app busy during the work – GaF Sep 06 '20 at 23:38