En la mayoría de las aplicaciones móviles modernas, un mismo botón puede ejecutar diferentes acciones dependiendo de cómo lo presionas:

  • Toque rápido: acción inmediata
  • Pulsación prolongada: acción avanzada o secundaria

🇬🇧Read in english

Este patrón de interacción es muy común y mejora significativamente la experiencia del usuario:

  • Permite reducir la cantidad de botones en pantalla
  • Hace que las interfaces sean más limpias e intuitivas
  • Ofrece al usuario la posibilidad de elegir entre una acción rápida o una más detallada sin tener que navegar por diferentes pantallas.

En Power Apps, por defecto, un botón ejecuta su lógica cuando el usuario lo toca. No existe una propiedad nativa para distinguir entre “toque corto” y una “pulsación larga”, ni tampoco propiedades como OnPressDown u OnPressUp. Pero… Combinando la propiedad pressed con un Timer, podemos recrear exactamente ese comportamiento.

Escenario práctico: control de inventario

Imagina una aplicación de inventario utilizada por operarios en un almacén. Cada vez que se reciben productos, deben actualizar el stock en tiempo real:

  • Si llegan unidades sueltas, lo lógico es pulsar el botón de “+” para sumar 1 artículo rápidamente.
  • Pero si llega un lote grande, tener que pulsar 50 veces el botón no tiene sentido. En ese caso, lo ideal es que con una pulsación prolongada, aparezca un pop-up que permita indicar manualmente la cantidad a añadir.

Con un poco de lógica en Power Fx, podemos hacer que un mismo botón tenga dos comportamientos distintos sin necesidad de conectores externos ni componentes complejos. En ese post te muestro paso a paso cómo implementarlo:

Paso 1: Crea las variables globales

Puedes inicializarlas en el App.OnStart, aunque a mi personalmente me gusta más inicializarlas en la propiedad OnVisible de la pantalla:

Set(_LongPressing_, false);
Set(_SeePopUp_, false);
Set(varStock, 0);
  • _LongPressing_: será nuestra “bandera” para saber si la pulsación ha superado el umbral que consideramos “larga”.
  • _SeePopUp_: controla la visibilidad del popup que se mostrará al mantener presionado.
  • varStock: representa el stock actual, para que podamos sumar unidades rápidamente al pulsar.

Paso 2: Configurar el botón

La propiedad OnSelect del botón se ejecuta cuando el usuario termina de pulsar el botón, no cuando comienza a hacerlo. Por ello, estableceremos en dicha propiedad la siguiente fórmula:

If(
    _LongPressing_,
    Set(_SeePopUp_, true),
    Set(varStock, varStock + 1)
)

Cuando se suelta el botón, se evalúa el valor actual de _LongPressing_:

  • Si _LongPressing_ es true: significa que el usuario mantuvo pulsado más tiempo del umbral, por lo tanto mostramos el popup.
  • Si es false: fue una pulsación corta, simplemente incrementamos el stock

Aquí no necesitamos medir el tiempo manualmente: solo confiamos en la bandera que controlará el timer.

Paso 3: Configurar el Timer

Primeramente vamos a configurar algunas propiedades básicas del Timer, para que se comporte como nosotros queremos:

PropiedadValorExplicación
Duration500Tiempo umbral en milisegundos para considerar pulsación larga.
StartButton1.PressedEl timer comienza a contar cuando se presiona el botón.
Reset!Button1.PressedEl timer se reinicia automáticamente al soltar el botón.
RepeatfalseEl timer no se repetirá, solo corre una vez.
AutoStartfalseSolo se inicia cuando Start = true.
AutoPausefalseEvita pausas inesperadas en dispositivos táctiles.
  • Al presionar el botón, Button1.Pressed pasa a true, por lo tanto el Timer arrancará.
  • Si se mantiene presionado el tiempo suficiente (más de 500ms), el Timer llega a su fin y dispara OnTimerEnd.
  • Si se suelta antes, el Timer se reinicia automáticamente y nunca llega a completar su duración

De esta forma, no medimos el tiempo directamente, simplemente detectamos si el Timer llegó o no al final.

Paso 4: Lógica de eventos del Timer

Ahora añadiremos lógica adicional al Timer, de manera que el botón se comporte como nosotros queremos:

OnTimerStart:

Set(_LongPressing_, false)

Cada vez que comienza una pulsación, nos aseguramos de que _LongPressing_ se reinicie a false. Esto es importante para evitar que el estado se quede atascado de una pulsación anterior.

OnTimerEnd:

Set(_LongPressing_, true);
Set(_SeePopUp_, true)

Si el Timer completa su duración, significa que la pulsación fue suficientemente larga, por tanto, establecemos _LongPressing_ en true.

En este caso también abrimos directamente el popup (aunque esto es opcional, si prefieres puedes quitar esta línea y dejar que la apertura ocurra en el OnSelect del botón). A mi personalmente me gusta más que el popup se abra aunque el usuario no haya soltado el botón.

Si sueltas el botón antes de los 500ms, OnTimerEnd no se ejecuta, por lo que _LongPressing_ se mantiene en false y se ejecutará la acción de la pulsación corta.

Resultado final

Toque corto:

Acción del usuarioResultado
Toque corto (menos de 0,5 s)Se incrementa el stock en 1

Toque largo:

Acción del usuarioResultado
Pulsación prolongada (> 0,5 s)Se abre el popup para introducir una cantidad manual

Conclusión

Este patrón basado en pulsación corta vs pulsación prolongada demuestra cómo, con muy pocos controles y un poco de lógica, se pueden crear interacciones avanzadas y fluidas en Power Apps.

Aunque la plataforma no incluye de forma nativa eventos como OnPressDown o OnPressUp, el uso combinado de la propiedad Pressed con un Timer permite reproducir ese comportamiento de forma confiable y sencilla. Con esta técnica, no estamos midiendo milisegros a mano ni creando lógica complicada, simplemente establecemos un umbral temporal que nos permite distinguir entre un toque rápido y una pulsación intencionada.

Esta solución convierte un simple botón en una interacción inteligente y contextual, alineada con los estándares de usabilidad que vemos en las mejores apps móviles. Y lo mejor: sin conectores, sin componentes personalizados, sin código externo.

Leave a comment

Autor

👋Soy Eugenio Peraza, consultor y desarrollador de soluciones con Power Platform.

Entusiasta de la tecnología con enfoque al negocio🚀

🔗 LinkedIn
📺 YouTube

©️2025 Power Tower