Sheet es un componente de interfaz que aparece en la parte inferior de la pantalla sobre el contenido principal y proporciona acciones o información adicional. Bottom Sheet es el tipo más común, definido en las guías de Material Design 3 (Google, 2024). A diferencia de las ventanas de diálogo, un Sheet no bloquea completamente la interacción con el fondo y admite los estados collapsed y expanded. Comprender los tipos y el comportamiento de Sheet es necesario para construir una navegación cómoda en aplicaciones móviles.
Puntos clave
Sheet es un componente de interfaz superficial que se desliza desde la parte inferior de la pantalla y muestra contenido o acciones adicionales sin sacar al usuario de la pantalla actual. A diferencia de las transiciones a pantalla completa, un Sheet conserva el contexto: el usuario ve la pantalla de fondo y entiende de dónde apareció el Sheet.
La arquitectura de un Sheet se basa en un contenedor de altura ajustable. En su estado mínimo (collapsed), solo es visible una parte del contenido, normalmente un título o un panel pequeño. El usuario puede arrastrar el Sheet hacia arriba para expandirlo (expanded) o deslizarlo hacia abajo para cerrarlo. Este comportamiento recuerda a una hoja de papel física que se extrae de debajo de una pila — de ahí su nombre.
Google en las guías de Material Design 3 (2024) destaca dos escenarios clave para usar Sheet: mostrar acciones adicionales que no caben en la barra de herramientas principal, y presentar formularios o información detallada sin navegar a una pantalla separada. En iOS, Apple añadió soporte nativo de Sheet desde iOS 15 mediante UISheetPresentationController, lo que confirma la universalidad del patrón.
Material Design define tres tipos de Bottom Sheet, cada uno con su propio comportamiento y ámbito de aplicación. Elegir el tipo correcto afecta directamente a la experiencia del usuario y al cumplimiento de las guías de la plataforma.
Bottom Sheet estándar es un componente no modal: el usuario puede interactuar con la pantalla de fondo sin cerrar el Sheet. Por ejemplo, mientras navega por una lista de productos en segundo plano, el usuario ve los filtros en un Bottom Sheet y puede modificarlos sin cerrar el panel. El Sheet ajusta su altura al contenido — del 30% al 90% de la pantalla.
El Bottom Sheet estándar no bloquea el fondo y permite la interacción con el contenido principal. Esta es una diferencia clave con respecto al Sheet modal, que requiere una acción obligatoria para continuar. Utilice un Sheet estándar cuando la información adicional no sea crítica para el escenario principal.
Bottom Sheet modal bloquea la interacción con la pantalla de fondo hasta que el usuario realice una acción dentro del Sheet. Este Sheet siempre se muestra en estado expandido y requiere un cierre explícito — mediante un botón, una acción o un deslizamiento hacia abajo. Material Design recomienda el Sheet modal para formularios de inicio de sesión, confirmaciones y ajustes críticos.
En Android, el Bottom Sheet modal se implementa mediante BottomSheetDialogFragment, que bloquea automáticamente el fondo. En iOS, un comportamiento similar lo proporciona la variante modal de UISheetPresentationController con el parámetro .mediumDetent. El Sheet modal solo debe usarse cuando el contexto requiere la atención del usuario.
Bottom Sheet expandido combina las propiedades del estándar y el modal: comienza como no modal en estado collapsed, pero al arrastrarlo hacia arriba se vuelve modal. En la práctica, esto significa que el usuario puede primero echar un vistazo al contenido y luego decidir si expande el Sheet para un estudio detallado o lo cierra.
Este patrón es especialmente popular en mapas y navegadores, donde el panel inferior muestra información breve sobre un punto de ruta y, al deslizar hacia arriba, se expande con detalles. Google Maps utiliza exactamente este Sheet expandido para mostrar información sobre lugares y rutas.
| Tipo de Sheet | Bloqueo de fondo | Estado inicial | Ejemplo |
|---|---|---|---|
| Estándar | No | Collapsed | Filtros en catálogo |
| Modal | Sí | Expanded | Formulario de inicio de sesión |
| Expandido | Parcial | Collapsed | Tarjeta de lugar |
Android SDK proporciona varias API para implementar Bottom Sheet, desde el enfoque clásico basado en View hasta el moderno Jetpack Compose. La librería Material Components para Android incluye implementaciones listas de BottomSheetDialogFragment y BottomSheetBehavior.
BottomSheetBehavior es una clase de Material Components que se adjunta a cualquier View y controla su posición en la pantalla. El desarrollador define tres estados: STATE_COLLAPSED, STATE_EXPANDED y STATE_HIDDEN. Behavior maneja automáticamente los gestos de arrastre y la animación.
val sheet = findViewById<View>(R.id.bottom_sheet)
val behavior = BottomSheetBehavior.from(sheet)
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
behavior.peekHeight = 200
Jetpack Compose proporciona una API más declarativa mediante el componente ModalBottomSheet de Material 3. A diferencia del enfoque basado en View, en Compose el Bottom Sheet es una función composable que recibe estado y contenido. El Sheet anima automáticamente la aparición, el cierre y los cambios de altura al arrastrar.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun FilterSheet(onDismiss: () -> Unit) {
ModalBottomSheet(onDismissRequest = onDismiss) {
Text("Filtros")
Button(onClick = onDismiss) { Text("Aplicar") }
}
}
BottomSheetDialogFragment es un DialogFragment especializado que se muestra como Bottom Sheet. Maneja automáticamente la modalidad, el ciclo de vida y los cambios de configuración. El desarrollador solo necesita sobrescribir onCreateView y devolver el layout del Sheet. Según la documentación de Google (Android Developers, 2024), BottomSheetDialogFragment es el método recomendado para Bottom Sheets modales en Android clásico.
Apple introdujo soporte nativo de Sheet desde iOS 15 mediante UISheetPresentationController. Antes de eso, los desarrolladores implementaban Bottom Sheet manualmente con transiciones personalizadas o librerías de terceros. El Sheet nativo de Apple admite detents — niveles de expansión predefinidos.
UISheetPresentationController es un controlador de presentación integrado que muestra un View Controller como Sheet. El desarrollador especifica un array de detents — valores de altura en los que el Sheet puede detenerse. iOS 16 añadió detents personalizados con altura arbitraria. Apple recomienda usar los detents medium (.medium) y large (.large) como principales.
let viewController = MySheetViewController()
if let sheet = viewController.sheetPresentationController {
sheet.detents = [.medium, .large]
sheet.prefersGrabberVisible = true
sheet.preferredCornerRadius = 16
}
present(viewController, animated: true)
SwiftUI proporciona el modificador .sheet, que vincula la visualización del Sheet a un estado. Cuando una variable publicada se vuelve true, SwiftUI muestra automáticamente el Sheet. SwiftUI también admite detents mediante el modificador .presentationDetents, añadido en iOS 16.
struct ContentView: View {
@State private var showSheet = false
var body: some View {
Button("Mostrar Sheet") { showSheet = true }
.sheet(isPresented: $showSheet) {
FilterView()
.presentationDetents([.medium, .large])
}
}
}
Los frameworks multiplataforma también admiten Bottom Sheet, adaptando el comportamiento a la plataforma de destino. Flutter y React Native proporcionan implementaciones integradas y personalizadas con distintos grados de flexibilidad.
Flutter SDK contiene dos métodos para mostrar Bottom Sheet: showBottomSheet (estándar) y showModalBottomSheet (modal). Material Design en Flutter sigue los mismos principios que en Android — el Sheet aparece desde abajo, admite arrastre y tiene altura ajustable. Para comportamiento expandido con detents se utiliza DraggableScrollableSheet.
Scaffold.of(context).showBottomSheet((context) {
return Container(
padding: EdgeInsets.all(16),
child: Column(
children: [
Text("Contenido del Sheet"),
ElevatedButton(
onPressed: () => Navigator.of(context).pop(),
child: Text("Cerrar")
)
]
)
);
})
React Native no tiene un componente Bottom Sheet integrado en su núcleo, por lo que los desarrolladores usan librerías de terceros. La más popular es @gorhom/bottom-sheet (más de 7 mil estrellas en GitHub, 2024). Proporciona un Bottom Sheet controlado por gestos con soporte para snap points, animaciones y encabezados fijos. La librería está construida sobre Reanimated 2 y Gesture Handler para rendimiento a 60 FPS.
El uso correcto de Bottom Sheet requiere cumplir con las guías de la plataforma y comprender los escenarios en los que un Sheet es adecuado. Revisemos las recomendaciones clave y los errores comunes al diseñar Sheets.
Bottom Sheet es óptimo para acciones que son complementarias al contenido principal de la pantalla. Filtros, ordenación, selección de opciones, información breve de un elemento — escenarios típicos. Material Design recomienda usar Bottom Sheet para herramientas que no deben ocupar toda la pantalla pero requieren más espacio que un Action Sheet o Popup Menu.
No utilice Bottom Sheet para advertencias críticas o errores — para esto son más adecuadas las ventanas de diálogo. Evite Sheets con gran cantidad de campos de entrada que requieran desplazamiento: el usuario tiene dificultades para llegar al teclado y pierde contexto. Si un Sheet contiene más de siete elementos de acción, considere una pantalla separada en lugar de un Sheet.
Un error típico es establecer peekHeight (altura en estado contraído) en más del 40% de la pantalla. El usuario no sabe si está viendo el Sheet completo o si se puede expandir. Material Design recomienda peekHeight entre el 15 y 30% de la altura de la pantalla para dejar una parte notable del contenido oculta y motivar el arrastre.
En iOS, los usuarios esperan poder cerrar un Sheet deslizando hacia abajo desde cualquier posición. Si desactiva este gesto (mediante UISheetPresentationController.prefersEdgeAttachedInCompactHeight), el usuario se frustra al intentar cerrar el Sheet de la forma habitual. Las guías de interfaz humana de Apple (2024) enfatizan que el deslizamiento para cerrar es una expectativa básica del usuario de iOS.
Preguntas frecuentes
Bottom Sheet no bloquea completamente el fondo y admite arrastre, mientras que una ventana de diálogo es modal y requiere una acción obligatoria. Bottom Sheet es más adecuado para opciones complementarias, el diálogo para confirmaciones críticas.
Sí, pero se requiere configurar adjustResize o adjustPan en el manifiesto de Android. En iOS, el teclado eleva automáticamente el Sheet. Flutter y React Native requieren manejo manual mediante MediaQuery para un posicionamiento correcto.
Se recomienda no más de 5-7 elementos en un Sheet estándar. Si hay más contenido, use desplazamiento o división en categorías. Material Design aconseja no superar el 90% de la altura de la pantalla en estado expandido.
Para un Sheet modal, establezca setCancelable(true) en Android o isModalInPresentation = false en iOS. En Jetpack Compose, onDismissRequest maneja automáticamente el toque en el fondo. En SwiftUI, el deslizamiento hacia abajo es el comportamiento predeterminado.
Sí, todas las implementaciones nativas admiten VoiceOver y TalkBack. Asegúrese de que FocusManager mueva correctamente el foco al Sheet al abrirlo y lo devuelva al cerrarlo. Las implementaciones personalizadas requieren configuración manual de accesibilidad.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también