es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Recargar datos de la tabla solo si se realiza un lanzamiento en frío o hay un cambio en la configuración.

Tengo una aplicación simple de dos pestañas que estoy tratando de manejar cuándo o si el List recarga datos desde la red.

Quiero que la aplicación solo recargue los datos cuando:
– Se inicia fríamente por primera vez (estado cerrado al inicio);
– Se pasa del estado .background al estado .active; o
– Se cambia una configuración en la SettingsView()

No quiero que el List recargue si se va a la SettingsView() sin cambiar una opción o simplemente cambiando de pestañas en general.

// vista de pestañas
struct Tabs: View {
 var body: some View {
  TabView {
   ViewOne().tabItem { Label("Configuración", systemImage: "gear") }
   ViewTwo().tabItem { Label("Lista", systemImage: "bag") }
  }
 }
}

// ViewOne
struct ViewOne: View {
 var body: some View {
  Text("Vista uno: Configuración")
  // interruptores y opciones aquí
   .onChange(of: option) { value in
    // hacer otras cosas aquí
    UserDefaults.standard.set(true, forKey: "reloadList")
   }
 }
}

// ViewTwo
struct ViewTwo: View {
 var body: some View {
 List(arrayItems) { item in
 }
  .onAppear {
   if( UserDefaults.standard.bool(forKey: "reloadList") ) {
    reloadData()
    UserDefaults.standard.removeObject(forKey: "reloadList")
   }
  }
 }
}

Lo anterior funciona cuando se ejecuta la aplicación y se cambian las configuraciones – el UserDefaults activa la función reloadData(). Esto también resuelve mi dilema de cambiar de pestañas (sin cambios en la configuración) y no recargar los datos.

Sin embargo, ahora me he perjudicado a mí mismo con una terrible experiencia de usuario, ya que la tabla no obtiene los datos en el inicio, ya sea en frío o en segundo plano.

Intenté agregar otro UserDefaults.standard.set(true, "coldLaunch") a la vista Tabs que luego establecería reloadList en true, pero eso no se activaba hasta que se cambiaba la pestaña y luego se volvía atrás.

También intenté establecer o activar reloadData() desde @Environment(\.scenePhase) var scenePhase, pero eso se activaba en cada inicio, igual que onAppear.

Tal vez no estoy pensando con claridad, ¡pero estoy tratando de encontrar el flujo correcto en el efecto y todavía no puedo entenderlo!

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para solucionar el problema de que la Lista no recarga los datos al iniciarse, puedes usar el modificador onReceive en ViewTwo para escuchar una notificación que se envía cuando la aplicación se vuelve activa o cuando se cambia la configuración. De esta manera, puedes recargar los datos si se cumplen algunas de estas condiciones.

    Aquí tienes un fragmento de código actualizado que incluye este cambio:

    // vista de pestañas
    struct Tabs: View {
        var body: some View {
            TabView {
                ViewOne().tabItem { Label("Configuración", systemImage: "gear") }
                ViewTwo().tabItem { Label("Lista", systemImage: "bag") }
            }
        }
    }
    
    // ViewOne
    struct ViewOne: View {
        var body: some View {
            Text("Vista uno: Configuración")
                // interruptores y opciones aquí
                .onChange(of: option) { value in
                    // hacer otras cosas aquí
                    NotificationCenter.default.post(name: .reloadListData, object: nil)
                }
        }
    }
    
    // ViewTwo
    struct ViewTwo: View {
        var body: some View {
            List(arrayItems) { item in
            }
            .onReceive(NotificationCenter.default.publisher(for: .reloadListData)) { _ in
                reloadData()
            }
            .onAppear {
                if (UserDefaults.standard.bool(forKey: "coldLaunch")) {
                    UserDefaults.standard.set(false, forKey: "coldLaunch")
                    NotificationCenter.default.post(name: .reloadListData, object: nil)
                }
            }
        }
    
        func reloadData() {
            // obtener datos de la red
        }
    }
    
    extension Notification.Name {
        static let reloadListData = Notification.Name("reloadListData")
    }
    

    En este código actualizado, estamos utilizando NotificationCenter.default para publicar una notificación llamada reloadListData cuando se cambia la configuración en ViewOne. En ViewTwo, estamos utilizando el modificador onReceive para escuchar esta notificación y recargar los datos si se recibe.

    También estamos utilizando el modificador onAppear para verificar si se trata de un inicio en frío y publicar la notificación reloadListData para obtener datos de la red.

    Esto debería resolver tu problema de cuándo recargar los datos de una manera más amigable para el usuario.

Comments are closed.