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.

@FetchRequest el predicado no se actualiza cuando cambia el valor de UserDefaults en SwiftUI.

Estoy teniendo problemas para descubrir cómo hacer que un @FetchRequest de SwiftUI use un predicado solo si un valor booleano almacenado en UserDefaults es true.

El problema es que FetchedResults no cambia cuando cambia el valor de showAvailable. Actualmente tengo que volver a iniciar la aplicación para ver los resultados basados en el valor de showAvailable.

“`
struct ContentView: View {
@AppStorage("showAvailable") private var showAvailable: Bool = false

<pre><code>@FetchRequest private var list: FetchedResults<item>

init() {
@AppStorage("showAvailable") var showAvailable = false
_list = FetchRequest(
sortDescriptors: [],
predicate: showAvailable ? NSPredicate(format: "parent == nil") : nil,
animation: .default
)
}

var body: some View {
Button("Cancelar") {
showAvailable.toggle()
}
}
</code></pre>

}
“`

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución para usar un @FetchRequest de SwiftUI con un predicado basado en un valor booleano en UserDefaults

    El problema con la implementación actual es que el envoltorio de propiedad @FetchRequest solo se evalúa una vez durante la inicialización de la vista. Esto significa que cambiar el valor de showAvailable en UserDefaults después de que se haya cargado la vista no cambiará el predicado utilizado para filtrar los FetchedResults.

    Para hacer que @FetchRequest use el predicado basado en el valor actual de showAvailable, debemos actualizar la propiedad list cada vez que cambie el valor de showAvailable.

    struct ContentView: View {
    
        @AppStorage("showAvailable") private var showAvailable: Bool = false
    
        @FetchRequest private var list: FetchedResults<item>
    
        init() {
            _list = FetchRequest(
                sortDescriptors: [],
                predicate: NSPredicate(format: "parent == %@", NSNull()),
                animation: .default
            )
        }
    
        var body: some View {
            Button("Alternar Disponibles") {
                showAvailable.toggle()
                updateList()
            }
        }
    
        private func updateList() {
            let predicate = showAvailable ? NSPredicate(format: "parent == nil") : NSPredicate(format: "parent == %@", NSNull())
            _list = FetchRequest(sortDescriptors: [], predicate: predicate, animation: .default)
        }
    
    }
    

    En esta implementación actualizada, introducimos un nuevo método privado updateList() que actualizará la propiedad list con el predicado correcto basado en el valor actual de showAvailable.

    La propiedad list en sí misma se establece inicialmente para filtrar los elementos secundarios de forma predeterminada, por lo que cambiar el valor de showAvailable a false actualizará la lista para mostrar solo elementos sin padre (parent == nil). Cambiarlo a true actualizará la lista para mostrar todos los elementos (parent == NSNull()).

    Al llamar a updateList() después de alternar el valor de showAvailable, aseguramos que FetchRequest se actualice con el predicado correcto, y la propiedad FetchedResults se vuelva a evaluar con el predicado cambiado.

Comments are closed.