VoiceOver è un lettore vocale integrato di Apple che vocalizza ogni elemento dell'interfaccia e consente di controllare il dispositivo tramite gesti. La tecnologia è integrata in iOS, iPadOS e macOS a livello di sistema e non richiede l'installazione di software aggiuntivo. Secondo Apple Accessibility (2025), VoiceOver supporta oltre 40 lingue ed è utilizzato da milioni di utenti non vedenti e ipovedenti in tutto il mondo.
Punti chiave
VoiceOver è un lettore vocale integrato nei sistemi operativi Apple. È progettato per utenti non vedenti e ipovedenti e fornisce un'interazione completa con il dispositivo senza contatto visivo. VoiceOver vocalizza tutti gli elementi dell'interfaccia: pulsanti, collegamenti, testo, immagini, notifiche ed elementi di sistema.
La tecnologia è stata presentata per la prima volta nel 2005 per macOS ed è apparsa su iOS con l'iPhone 3GS nel 2009. Da allora, VoiceOver è diventato parte integrante dell'ecosistema Apple e uno dei principali argomenti a favore dell'accessibilità della piattaforma. VoiceOver è integrato a livello di sistema — ciò significa che funziona in qualsiasi applicazione senza integrazione aggiuntiva da parte dello sviluppatore, sebbene la qualità della vocalizzazione dipenda direttamente da quanto bene l'applicazione utilizza l'API di accessibilità iOS.
VoiceOver supporta oltre 40 lingue con sintesi vocale naturale e si adatta alle impostazioni vocali regionali. Su iOS, VoiceOver utilizza i motori vocali di Siri per l'italiano e numerose altre lingue, garantendo un suono il più naturale possibile e un'intonazione corretta in base alla punteggiatura e al contesto.
VoiceOver intercetta gli eventi tattili e li interpreta in modo diverso dall'input standard di iOS. Quando un utente tocca lo schermo, VoiceOver non attiva l'elemento sotto il dito, ma prima lo vocalizza. Solo dopo un doppio tocco l'elemento viene attivato. Questa differenza fondamentale consente agli utenti non vedenti di esplorare l'interfaccia senza il rischio di clic accidentali.
VoiceOver legge gli elementi dell'interfaccia in ordine logico: da sinistra a destra, dall'alto verso il basso. L'ordine di lettura viene ereditato dalla gerarchia delle viste iOS, ma lo sviluppatore può modificarlo tramite la proprietà accessibilityElements per layout complessi. L'utente può spostarsi tra gli elementi scorrendo verso destra (successivo) e verso sinistra (precedente), nonché toccando un elemento specifico per farlo vocalizzare.
Ad ogni spostamento, VoiceOver pronuncia il tipo di elemento (pulsante, collegamento, titolo), il suo nome (accessibilityLabel), lo stato (selezionato, disabilitato) e il suggerimento (accessibilityHint). Se l'elemento contiene un valore — ad esempio, un cursore del volume — VoiceOver lo vocalizza anch'esso. Gli Accessibility Traits (UIAccessibilityTraits) informano inoltre l'utente sul comportamento dell'elemento: se è un pulsante, un interruttore, un campo di ricerca o un tasto della tastiera.
Il rotore è una manopola di regolazione virtuale che cambia la modalità di navigazione di VoiceOver. L'utente ruota il rotore con due dita (come una manopola del volume) e seleziona una modalità: parole, caratteri, titoli, collegamenti, punti di ingresso, righe di tabella e altre. La modalità titoli consente di passare rapidamente da H1-H6 nelle pagine web e nelle applicazioni, mentre la modalità caratteri pronuncia il testo lettera per lettera, utile durante la compilazione di moduli o l'inserimento di codici di verifica.
Lo sviluppatore può aggiungere modalità personalizzate al rotore tramite l'API UIAccessibilityCustomRotor. Ad esempio, in un'applicazione per appunti, è possibile aggiungere un rotore “Appunti preferiti” o “Modifiche recenti”. I rotori personalizzati accelerano significativamente la navigazione in applicazioni specifiche e sono considerati una best practice di accessibilità su iOS.
VoiceOver utilizza un proprio insieme di gesti che non corrispondono ai gesti standard di iOS. La maggior parte dei gesti viene eseguita con tre dita invece di uno — ciò previene conflitti con il funzionamento normale e consente a VoiceOver di funzionare simultaneamente con l'input standard.
| Azione | Gesto | Risultato |
|---|---|---|
| Vocalizzare elemento | Tocco con 1 dito | Pronuncia il nome dell'elemento |
| Attivare | Doppio tocco | Preme pulsante o collegamento |
| Elemento successivo | Scorrere a destra | Passare al successivo |
| Elemento precedente | Scorrere a sinistra | Tornare al precedente |
| Scorrere | Scorrere con 3 dita | Scorrere elenco o pagina |
| Rotore | Ruotare con 2 dita | Cambiare modalità di navigazione |
Il gesto del doppio tocco è il modo principale per attivare gli elementi in VoiceOver. Se un elemento richiede un'azione speciale (ad esempio, trascinare), VoiceOver utilizza la sequenza “tocco — doppio tocco e tenere” per entrare in modalità di movimento. Ciò consente di eseguire gesti complessi come il trascinamento senza vedere lo schermo. VoiceOver supporta anche il gesto “doppio tocco con due dita” per annullare un'azione e “triplo tocco” per attivare/disattivare la tendina dello schermo (Screen Curtain).
Uno sviluppatore di applicazioni iOS può migliorare significativamente l'interazione con VoiceOver tramite l'API UIAccessibility. Le impostazioni di accessibilità di base vengono aggiunte in Interface Builder (Identity Inspector → Accessibility), ma le interfacce complesse richiedono una configurazione programmatica nel codice.
La proprietà accessibilityLabel imposta il testo che VoiceOver pronuncia per l'elemento. Se nessuna etichetta è impostata, VoiceOver utilizza il testo del pulsante o il segnaposto del campo di testo. Per gli elementi senza testo (icone, viste personalizzate), l'etichetta è obbligatoria. La proprietà accessibilityTraits definisce il tipo di elemento: pulsante, titolo, interruttore, campo di ricerca, tasto della tastiera, valore cambia, collegamento e altri.
let profileButton = UIButton(type: .custom)
profileButton.setImage(UIImage(named: "avatar"), for: .normal)
profileButton.isAccessibilityElement = true
profileButton.accessibilityLabel = "Profilo utente"
profileButton.accessibilityTraits = .button
profileButton.accessibilityHint = "Apre la schermata delle impostazioni del profilo"
Il flag isAccessibilityElement abilita il supporto VoiceOver per le viste personalizzate — per impostazione predefinita è vero solo per gli elementi standard (UIButton, UILabel, UITextField). Il parametro accessibilityHint aggiunge un suggerimento: VoiceOver lo pronuncia dopo una pausa se l'utente si sofferma su un elemento. Il suggerimento dovrebbe descrivere il risultato dell'azione, non l'istruzione: “Apre la schermata delle impostazioni” invece di “Premere per aprire”.
Per schermate complesse in cui il gruppo logico di elementi non corrisponde all'ordine visivo, si utilizza accessibilityElements — un array che imposta l'ordine di lettura. Ad esempio, una scheda prodotto contiene un'immagine, un nome, un prezzo e un pulsante “Aggiungi al carrello”. Se questi elementi sono disposti in modo caotico nella gerarchia delle viste, accessibilityElements stabilisce l'ordine corretto per VoiceOver.
let productCard = UIView()
let productImage = UIImageView()
let productName = UILabel()
let productPrice = UILabel()
let addToCartButton = UIButton()
productCard.accessibilityElements = [
productImage, productName, productPrice, addToCartButton
]
Per combinare più elementi in un unico elemento accessibile, si utilizza UIAccessibilityContainer o accessibilityFrame per sovrascrivere l'area tattile. Ciò è utile quando una cella di tabella contiene più componenti dell'interfaccia ma rappresenta logicamente un unico elemento — VoiceOver dovrebbe vocalizzare l'intera cella nel suo insieme, non iterare attraverso il suo contenuto singolarmente.
La corretta configurazione dell'accessibilità per VoiceOver richiede attenzione a diversi aspetti: markup semantico, aggiornamenti dinamici, gestione degli elementi personalizzati e test con un vero lettore vocale.
In SwiftUI, l'accessibilità viene configurata tramite i modificatori .accessibilityLabel(), .accessibilityValue(), .accessibilityHint() e .accessibilityAddTraits(). SwiftUI eredita automaticamente l'accessibilità dagli elementi standard, ma i componenti personalizzati richiedono una configurazione esplicita. Ad esempio, un cursore personalizzato deve comunicare a VoiceOver il suo valore e il formato di modifica.
Slider(value: $volume, in: 0...100)
.accessibilityLabel("Volume")
.accessibilityValue(
Text("\(Int(volume)) percento")
)
.accessibilityAddTraits(.adjustsAudioForAccessibility)
.accessibilityAdjustableAction { direction in
switch direction {
case .increment: volume = min(volume + 5, 100)
case .decrement: volume = max(volume - 5, 0)
}
}
Il modificatore accessibilityAdjustableAction aggiunge la possibilità di modificare i valori con i gesti di VoiceOver: scorrere verso l'alto per aumentare, scorrere verso il basso per diminuire. Senza questo modificatore, il cursore rimarrà inaccessibile per il controllo tramite lettore vocale. Una configurazione simile è richiesta per stepper personalizzati, selettori e altri elementi che modificano il loro valore.
Quando il contenuto sullo schermo cambia dinamicamente (appare una notifica, lo stato di caricamento si aggiorna, un prezzo cambia), VoiceOver deve ricevere una notifica tramite UIAccessibility.post. Senza questa chiamata, il lettore vocale non saprà delle modifiche e l'utente perderà informazioni importanti. Per SwiftUI, si utilizza il modificatore .accessibilityAnnouncement().
UIAccessibility.post(
notification: .announcement,
argument: "Prezzo ridotto del 20 percento"
)
// SwiftUI
Text("Prezzo aggiornato")
.accessibilityAnnouncement(Text("20% di sconto"))
Le notifiche di VoiceOver dovrebbero essere utilizzate in modo oculato: annunci eccessivi infastidiscono l'utente, mentre la loro assenza rende l'applicazione inaccessibile. La strategia ottimale è annunciare solo i cambiamenti che influenzano il flusso di lavoro corrente dell'utente: aggiornamenti del carrello, stato di caricamento, errore di convalida del modulo, notifica della chat. I cambiamenti in background (ora sul pannello, tassi di cambio) non richiedono annuncio — l'utente li verificherà quando necessario.
Il test di VoiceOver viene eseguito utilizzando un dispositivo fisico con il lettore vocale attivato o un simulatore iOS con l'opzione Accessibility Inspector. È importante testare scenari di utilizzo completi: completare una registrazione, effettuare un ordine, trovare un prodotto tramite ricerca senza controllo visivo. Se il flusso è navigabile senza feedback visivo — VoiceOver è configurato correttamente.
Domande frequenti
Impostazioni → Accessibilità → VoiceOver. Attiva l'interruttore. Per l'attivazione rapida, utilizza il triplo clic del pulsante laterale (su iPhone X e successivi) o del pulsante Home. Siri può anche attivare VoiceOver con il comando “Attiva VoiceOver”.
VoiceOver è il lettore vocale di Apple per iOS, TalkBack è il lettore vocale di Google per Android. Il principio di funzionamento è lo stesso: toccare vocalizza, il doppio tocco attiva. La differenza sta nei gesti, nelle impostazioni del rotore e nelle integrazioni ecosistemiche: VoiceOver è più profondamente integrato con iCloud e Apple Pay.
Utilizza l'API UIAccessibility: imposta accessibilityLabel per tutti gli elementi, accessibilityTraits per il tipo di elemento e accessibilityHint per i suggerimenti. In SwiftUI, utilizza i modificatori .accessibilityLabel() e .accessibilityAddTraits(). Testa l'applicazione con VoiceOver attivato.
Il rotore è una modalità di navigazione cambiata ruotando due dita. Determina come spostarsi tra gli elementi: per titoli, caratteri, parole, collegamenti o punti di ingresso. Gli sviluppatori possono aggiungere le proprie modalità tramite UIAccessibilityCustomRotor.
Per UIView personalizzato, è necessario impostare isAccessibilityElement = true e fornire accessibilityLabel. Se l'elemento è composto da più viste figlie, utilizza accessibilityElements per impostare l'ordine di lettura o combinale in un contenitore.
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