Cómo agregar una barra de búsqueda en SwiftUI

Una barra de búsqueda puede mejorar la experiencia del usuario en nuestras aplicaciones al permitirles encontrar información rápidamente.

Gracias al modificador searchable, podemos agregar una barra de búsqueda en SwiftUI. Veamos un ejemplo:

Preparando los datos

Primero, creamos la estructura que necesitaremos. En un nuevo proyecto de iOS con SwiftUI, abre ContentView.swift y coloca el siguiente código justo antes de la declaración de ContentView:

struct Employee: Identifiable {
let id = UUID()
let name: String
var active: Bool = true
}

Esta estructura contendrá los datos de los empleados que queremos filtrar.

Ahora, dentro de ContentView y antes de la propiedad body, agrega el siguiente código:

// 1
private let employees = [
Employee(name: "Angela"),
Employee(name: "Pam", active: false),
Employee(name: "Dwight"),
Employee(name: "Jim", active: false),
Employee(name: "Michael", active: false),
Employee(name: "Oscar")
]
// 2
@State private var criteria = ""

Este código realiza lo siguiente:

  1. Crea un arreglo de Employee que será nuestra fuente de datos.
  2. Define una variable de estado que contendrá el criterio de búsqueda.

Preparando la vista

Dentro de body, reemplaza el código existente con el siguiente:

NavigationStack {
List {
ForEach(filteredItems) { employee in
Text(employee.name)
}
}
}
.searchable(text: $criteria, prompt: "Employee name")

Con este código creamos un NavigationStack que contiene un List que mostrará todo los empleados contenidos en la variable filteredItems. Además hemos agregado el modificador searchable(text:placement:prompt:) que se encarga de incluir la barra de búsqueda al NavigationStack.

Veras un error de compilación para corregirlo, agrega la variable filteredItems. Esta es una variable calculada que retorna los empleados tomando en cuenta el valor de criteria para filtrarlos:

var filteredItems: [Employee] {
if criteria.isEmpty {
return employees
} else {
return employees.filter { $0.name.localizedCaseInsensitiveContains(criteria)
}
}
}

Si criteria está vacía, este código retornará la lista completa; de lo contrario, filtrará los empleados según el valor de la propiedad name.

Ejecuta el proyecto e introduce la letra A en la barra de búsqueda para ver la funcionalidad en acción.

Simulador de iOS mostrando un listado de empleados los cuales son filtrados cuando introducimos la letra "A"

Agregando Scopes

La barra de búsqueda puede complementarse utilizando searchScopes(_:scopes:). Con este modificador, podemos refinar el criterio de búsqueda al permitir que el usuario indique la categoría de búsqueda.

Justo debajo de la declaración de Employee, agrega el siguiente enum:

enum Scope: String, CaseIterable {
case active, inactive
}

Luego, debajo de la declaración de criteria, agrega:

@State private var scope = Scope.active

Hemos añadido un enum con las opciones que queremos mostrar y una variable de estado, scope, para guardar los cambios según lo indique el usuario. scope por defecto tiene el valor Scope.active, por lo que la primera vez que se muestre la lista solo podremos visualizar los empleados activos.

Debajo de .searchable(text:placement:prompt:), agrega el siguiente código:

.searchScopes($scope) {
ForEach(Scope.allCases, id: \.self) { scope in
Text(scope.rawValue.capitalized)
}
}

Este código agrega searchScopes(_:scopes:), que nos permite indicar la variable de estado que almacenará el scope deseado.

Para que esto funcione, debemos modificar filteredItems para que tome en cuenta el valor de scope:

var filteredItems: [Employee] {
// 1
let isActive = scope == .active
if criteria.isEmpty {
// 2
return employees.filter { $0.active == isActive }
} else {
// 3
return employees.filter { $0.name.localizedCaseInsensitiveContains(criteria) && $0.active == isActive
}
}
}

Este código realiza lo siguiente:

  1. Utiliza la variable isActive para almacenar un valor booleano que indica si estamos filtrando solo empleados activos.
  2. Si criteria está vacío, filtra solo por la propiedad active.
  3. En caso contrario, filtra por name y active.

Ejecuta la aplicación para ver la nueva funcionalidad en acción:

Simulador de iOS mostrando un listado de empleadosque se filtran utilizando texto e indicando el tipo de empleado

Otras cosas a tomar en cuenta

Si quisieras reaccionar cuando el usuario presiona la tecla search del teclado puedes usar el modificador onSubmit(of:_:), por ejemplo:

.onSubmit(of: .search, filterEmployees)

Comparte este artículo

Subscríbete a nuestro Newsletter

Mantente al día en el mundo de las aplicaciones móviles con nuestro blog especializado.

Artículos semanales

Todas las semanas artículos nuevos sobre el mundo de las aplicaciones móviles.

No spam

No te enviaremos spam, solo contenido de calidad. Puedes darte de baja cuando quieras.

Contenido de calidad

Nada de contenido generado de manera automática usando ChatGPT.

Recomendaciones

Tips indispensables sobre mejores prácticas y metodologías.

© 2024 AsyncLearn