Tap è il gesto base delle interfacce touch: un singolo tocco dello schermo con un dito seguito dal rilascio. Tap è l'azione primaria nei sistemi operativi mobili — aprire app, premere pulsanti, selezionare elementi di elenco. Viene riconosciuto in 100–300 ms e genera un evento di clic. Su iOS viene gestito tramite UITapGestureRecognizer, su Android — tramite setOnClickListener o View.onClick.
Punti chiave
Tap (tocco, pressione) è il gesto di toccare rapidamente il touchscreen con un dito o uno stilo. Il gesto consiste in due fasi: tocco verso il basso e rilascio, che avvengono nello stesso punto senza movimento. Il sistema riconosce un Tap quando l'intervallo di tempo tra down e up non supera un valore di soglia (di solito 300–500 ms). Se l'utente tiene il dito più a lungo — il gesto diventa una pressione lunga.
Tap è il fondamento dell'UX mobile. Su tutte le piattaforme mobili, Tap sostituisce il clic sinistro del mouse utilizzato nelle interfacce desktop. A differenza del clic del mouse, Tap non ha modificatori (Shift+clic, Ctrl+clic) e non ha hover — questo limite modella il design delle interfacce mobili. Per compensare la mancanza di anteprima, le piattaforme mobili utilizzano feedback visivo: evidenziazione al tocco, effetto ripple in Android, cambio di opacità in iOS.
Anatomia di Tap include cinque fasi a livello di sistema: attivazione del sensore (tocco), determinazione delle coordinate, filtro del rumore (il dito non deve spostarsi più di una distanza soglia), attesa di completamento (rilascio o mantenimento), classificazione (Tap, pressione lunga, trascinamento). I controller touch moderni elaborano questo ciclo in 8–16 ms a una frequenza di polling di 60–120 Hz.
Tap e Click sono eventi diversi con fisica diversa. Click è un evento del mouse che si verifica quando il pulsante del mouse viene premuto e rilasciato nella stessa posizione. Tap è un evento del touchscreen che si verifica quando un dito tocca. Sui dispositivi mobili, il browser converte Tap in un evento click con un ritardo di 300–350 ms (per emulare lo zoom a doppio tocco). Questo ritardo è stato storicamente un problema per il web mobile finché Apple e Google non hanno introdotto meta viewport con user-scalable=no.
| Parametro | Tap (touch) | Click (mouse) |
|---|---|---|
| Dispositivo di input | Dito, stilo | Cursore del mouse |
| Fasi | touchstart → touchend | mousedown → mouseup |
| Anteprima (hover) | Non disponibile | Disponibile (hover) |
| Ritardo | 0–500 ms | 0 ms |
| Precisione | Bassa (dito più largo del cursore) | Alta (a livello di pixel) |
| Modificatori | Nessuno | Shift, Ctrl, Cmd |
| Multipli | Multitouch (2+ dita) | No (cursore singolo) |
Touch Events è un'API separata da Mouse Events. Gli eventi touch (touchstart, touchmove, touchend) trasmettono un array di punti di contatto (TouchList), coordinate, pressione e dimensione dell'area di contatto (radiusX, radiusY). Mouse Events trasmette solo le coordinate del cursore. I browser moderni sintetizzano un click da touchend se non c'è stato movimento del dito e nessun evento touchcancel. Pointer Events API combina entrambi gli approcci, fornendo una gestione unificata per tutti i dispositivi di input.
UITapGestureRecognizer è il riconoscitore standard di Tap singolo e multiplo nell'SDK iOS. Supporta la configurazione di numberOfTapsRequired (numero di tocchi sequenziali) e numberOfTouchesRequired (numero di dita che toccano simultaneamente). Il riconoscitore passa allo stato UIGestureRecognizerStateRecognized quando l'utente rilascia il dito e il tocco non supera la soglia di movimento.
// UITapGestureRecognizer con supporto Double Tap
class InteractiveImageViewController: UIViewController {
private var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Single Tap — mostra/nascondi controlli
let singleTap = UITapGestureRecognizer(
target: self,
action: #selector(handleSingleTap)
)
imageView.addGestureRecognizer(singleTap)
// Double Tap — zoom immagine
let doubleTap = UITapGestureRecognizer(
target: self,
action: #selector(handleDoubleTap)
)
doubleTap.numberOfTapsRequired = 2
// Single Tap si attiva solo se Double Tap non viene riconosciuto
singleTap.require(doubleTap.toFail())
imageView.addGestureRecognizer(doubleTap)
}
@objc private func handleSingleTap() { /* mostrare i controlli */ }
@objc private func handleDoubleTap() { /* zoom */ }
}Pattern importante: quando si supportano simultaneamente Tap singolo e doppio, è necessario chiamare require(_:toFail:). Senza questo, il tap singolo si attiverà immediatamente, non permettendo al sistema di attendere una seconda pressione. iOS supporta anche il riconoscimento di Tap tramite UIControl.addTarget — per UIButton, UISwitch e altri controlli. I controlli integrati di UIKit hanno già una gestione standard di Tap, e aggiungere UITapGestureRecognizer sopra di essi può causare conflitti.
View.setOnClickListener è il metodo standard dell'SDK Android per gestire i clic su View. Quando un utente tocca una View e rilascia il dito sullo stesso elemento (touch down → touch up all'interno della View), viene chiamato il metodo onClick(). Android aggiunge automaticamente un effetto ripple (su API 21+) con animazione tattile. Un pulsante è considerato premuto nello stato PRESSED, che viene visualizzato visivamente tramite un selettore o RippleDrawable.
// setOnClickListener in Fragment con Data Binding
class ItemListFragment : Fragment() {
private var binding: FragmentItemListBinding? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentItemListBinding.bind(view)
binding.submitButton.setOnClickListener {
submitForm()
}
// Listener con debounce per evitare doppio clic
binding.submitButton.setOnClickListener(
DebouncingClickListener {
submitForm()
}
)
}
private fun submitForm() {
// Invio dati del modulo
}
}Debounce è un pattern importante nello sviluppo Android. Un utente potrebbe premere accidentalmente un pulsante due volte in un breve periodo, causando un doppio invio del modulo o una doppia esecuzione dell'azione. Soluzione: un wrapper DebouncingClickListener che blocca i clic ripetuti per 500–1000 ms. Google raccomanda questo approccio negli esempi ufficiali di Android Architecture Components. Per RecyclerView, viene fornito setOnItemClickListener tramite ListAdapter con un'interfaccia di callback.
Double Tap (doppio tocco) — due tocchi consecutivi con un intervallo non superiore a 300–400 ms. Utilizzato per ingrandire immagini (mappe, foto), mettere mi piace nei social network (Instagram, Twitter), tornare all'inizio di un elenco (Telefono, Messaggi). Triple Tap (triplo tocco) è meno comune — utilizzato principalmente per funzioni di accessibilità (modalità schermo intero, VoiceOver) e nei giochi.
Implementazione del Double Tap richiede sincronizzazione con il Tap singolo: se si aggiungono entrambi i gesti a un elemento, il Tap singolo si attiverà con ritardo (il sistema attende una seconda pressione). In iOS, questo ritardo è gestito tramite require(toFail:) — il Tap singolo viene posticipato fino a quando non si è certi che il Double Tap non si verificherà. In Android, viene utilizzato GestureDetector.OnDoubleTapListener con i callback onSingleTapConfirmed e onDoubleTap. onSingleTapConfirmed viene chiamato solo dopo un timeout quando il sistema è sicuro che si tratti di un tocco singolo.
// Double Tap in Android tramite GestureDetector
class PhotoViewerActivity : AppCompatActivity() {
private var gestureDetector: GestureDetector? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
gestureDetector = GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
toggleControls() // mostra/nascondi controlli
return true
}
override fun onDoubleTap(e: MotionEvent): Boolean {
zoomToPoint(e.x, e.y) // zoom al punto di tocco
return true
}
})
}
}Double tap stile Instagram è un pattern UX popolare per le app social. Il doppio tocco su una foto attiva un'animazione di like (icona a forma di cuore). Viene implementato tramite GestureDetector in Android o UITapGestureRecognizer con numberOfTapsRequired=2 in iOS. Per l'animazione, viene utilizzato Core Animation su iOS e ObjectAnimator/AnimatorSet su Android. Il tempo di risposta del double tap deve essere minimo — l'utente si aspetta un'animazione istantanea dopo il secondo tocco.
Le Human Interface Guidelines di Apple e Material Design di Google hanno requisiti specifici per Tap. Dimensione minima del target tattile: 44×44 pt per iOS e 48×48 dp per Android. Ciò corrisponde a ~9 mm sullo schermo — la dimensione del polpastrello di un adulto medio. La distanza tra i target tattili deve essere di almeno 8 pt/dp per evitare tocchi accidentali.
| Regola | Valore | Motivazione |
|---|---|---|
| Dimensione minima del target | 44×44 pt (iOS) / 48×48 dp (Android) | Dimensione media del polpastrello ~9 mm |
| Spaziatura tra i target | ≥8 pt / ≥8 dp | Prevenzione di tocchi accidentali |
| Feedback visivo | Evidenziazione / Ripple | Conferma della registrazione del tocco |
| Durata dell'animazione di tocco | 100–200 ms | Sufficiente per la percezione, non rallenta l'interfaccia |
| Gestione del Double Tap | Richiede ritardo del Tap singolo | Prevenzione di attivazione accidentale |
| Aree di bordo dello schermo | Zona di impatto aumentata | Compensazione della presa del dispositivo |
Il feedback visivo è obbligatorio per Tap. L'utente deve vedere che il tocco è stato registrato: cambio di colore, opacità, animazione ripple o evidenziazione. Senza feedback, l'utente potrebbe toccare di nuovo, causando azioni indesiderate. In iOS, l'animazione standard di evidenziazione del tocco è un cambio di opacità a 0.3 con durata di 0.15 s. In Android — effetto ripple Material che si diffonde dal punto di contatto. Non ritardare il feedback visivo — l'utente deve vedere la reazione simultaneamente al tocco.
Domande frequenti
Tap è un evento tattile, Click è un evento del mouse. Nel browser, Tap viene convertito in Click con un ritardo di 300 ms (per distinguerlo dallo zoom a doppio tocco). I browser moderni (Chrome 32+, Safari 9.1+) disabilitano questo ritardo con meta viewport width=device-width. Usa Pointer Events API per una gestione unificata: pointerdown/pointerup funzionano per tutti i dispositivi di input (mouse, touch, stilo).
Il target tattile minimo è di 44×44 punti (iOS) o 48×48 dp (Android). Ciò corrisponde approssimativamente a 9×9 mm su uno schermo fisico. Se un pulsante è visivamente più piccolo (ad esempio, un'icona 24×24), aumenta l'area di impatto tramite UIEdgeInsets (iOS) o TouchDelegate (Android). La spaziatura tra target adiacenti deve essere di almeno 8 unità per evitare tocchi accidentali.
La prevenzione del doppio clic viene implementata tramite un meccanismo di debounce: dopo il primo clic, il pulsante viene bloccato per 500–1000 ms. In Android, usa DebouncingClickListener (una soluzione pronta di Architecture Components). In iOS, disabilita isEnabled del pulsante immediatamente dopo la pressione e riabilitarlo tramite DispatchQueue.main.asyncAfter. Nelle applicazioni web, imposta il flag disabled sull'elemento button dopo il primo clic.
Long Tap (pressione lunga) è tenere il dito sullo schermo per 500+ ms senza muoversi. Tap è un tocco rapido (100–300 ms). Tap esegue l'azione principale, Long Tap esegue un'azione secondaria (menu contestuale, modifica). Su iOS, Tap è gestito da UITapGestureRecognizer, la pressione lunga da UILongPressGestureRecognizer. Su Android — setOnClickListener vs setOnLongClickListener.
Sì, gli stili sono gestiti come Tap tramite l'API tattile standard. Apple Pencil trasmette forza (pressione), altitudeAngle e azimuth. S Pen in Android trasmette parametri simili tramite MotionEvent.getPressure() e getAxisValue(MotionEvent.AXIS_TILT). Per gli stili, puoi ridurre il target tattile a 24×24 punti poiché la precisione dello stilo è superiore a quella di un dito.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche