Marceloawq
Marceloawq

Reputation: 173

Display activity indicator while fetching api data

I'm filling this Picker with data from my api

var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Pesquisar Denúncia")) {
                //some code...
                    Picker(selection: $tipoDenunciaSelecionada, label: Text("Tipo de Denúncia")) {
                        ForEach(tiposDenuncia, id: \.self) {item in
                            Text(item.nome ?? "")
                        }
                    }.onAppear(perform: carregarTipoDenuncia)
                   
             //some more code...
       }
    }

For fetch data, i made this func

func carregarTipoDenuncia()  {
        self.estaCarregando = true
        let oCodigo_Entidade = UserDefaults.standard.integer(forKey: "codigoEntidade")
        
        guard let url = URL(string: "url here") else {
            print("Erro ao conectar")
            return
        }
        let request = URLRequest(url: url)
        let task = URLSession.shared.dataTask(with: request) {data, response, error in
            let decoder = JSONDecoder()
            if let data = data {
                do {
                    let response = try decoder.decode([TipoDenunciaModel].self, from: data)
                    DispatchQueue.main.async {
                        self.tiposDenuncia = response
                    }
                    
                    return
                } catch  {
                    print(error)
                }
            }
            
        }
       
        task.resume()
    }

but now i dont know to display an indicator that the data is being downloaded. I tried adding a state boolean variable and manipulating it after response to show/hide an actionsheet but it didnt worked, the actionsheet didnt disapear. I need the user to select at least one of the options of this picker. How can i display some indicator that the data is loading?

Upvotes: 0

Views: 6748

Answers (2)

West1
West1

Reputation: 1918

You can use a determinate SwiftUI ProgressView, as seen here.

Example usage:

import SwiftUI

struct ActivityIndicator: View {
    @State private var someVar: CGFloat = 0.0 //You'll need some sort of progress value from your request

    var body: some View {
        ProgressView(value: someVar)
    }
}

Upvotes: 0

vadian
vadian

Reputation: 285150

As you can show any view in body add a boolean @State variable with initial value true and show a ProgressView. After loading the data set the variable to false which shows the Picker.

Move the .onAppear modifier to after Form.

var body: some View {
    @State private var isLoading = true
    // @State private var tipoDenunciaSelecionada ...

        NavigationView {
            Form {
                Section(header: Text("Pesquisar Denúncia")) {
                //some code...
                    if isLoading {
                        HStack(spacing: 15) {
                            ProgressView()
                            Text("Loading…")
                        }
                    } else {
                        Picker(selection: $tipoDenunciaSelecionada, label: Text("Tipo de Denúncia")) {
                            ForEach(tiposDenuncia, id: \.self) {item in
                                Text(item.nome ?? "")
                            }
                    }
                   
             //some more code...
            }.onAppear(perform: carregarTipoDenuncia)
       }
    }
}

let response = try decoder.decode([TipoDenunciaModel].self, from: data)
     DispatchQueue.main.async {
        self.tiposDenuncia = response
        self.isLoading = false
     }
...

Upvotes: 1

Related Questions