ios - ¿Diferencia real entre UIAccessibilityLayoutChangedNotification y UIAccessibilityScreenChangedNotification?
(2)
Estas dos notificaciones son para contenido dinámico en vistas y para comunicar estos cambios a VoiceOver para usuarios de lectores de pantallas. Hay poca diferencia entre estas dos notificaciones, excepto por su comportamiento predeterminado, y el pequeño y tonto "boop beep" para las notificaciones de ScreenChange.
En ambos casos, el argumento
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, arg);
Representa una cadena para leer, o un elemento en pantalla, al cual VoiceOver cambiará su enfoque. En el caso de cambios dramáticos en el contexto, es importante enviar el foco a un lugar que tenga sentido o anunciar que tales cambios han tenido lugar. Cualquiera de los enfoques es aceptable desde el punto de vista de la accesibilidad, aunque prefiero enfoques que impliquen la menor cantidad posible de cambios. En el caso de cambios de diseño simples, casi siempre es mejor anunciar el cambio de contexto y dejar el foco donde estaba. Aunque a veces, el elemento que causó el cambio de contexto está oculto, y luego es claramente necesario dirigir la voz en off para resaltar el nuevo contenido, porque el comportamiento predeterminado en este caso no está definido o quizás es determinista, pero está determinado por un marco que no sabe absolutamente nada acerca de tu aplicación!
La diferencia entre los dos eventos, dado que ambos hacen exactamente lo mismo, está en su comportamiento predeterminado. Si proporciona nil a UIAccessibilityLayoutChangedNotification
es como si no hubiera hecho nada. Si proporciona un argumento nulo a UIAccessibilityScreenChangedNotification
, enviará el foco al primer UIObject en su jerarquía de vistas que esté marcado como un elemento de accesibilidad, una vez que todos los cambios de jerarquía de vistas y los dibujos se hayan completado.
UIAccessibilityLayoutChangedNotification
Un buen ejemplo de caso de uso para UIAccessibilityLayoutChangedNotification
es para formularios dinámicos. Desea que los usuarios sepan que, según las decisiones que tomaron en el formulario, hay nuevas opciones disponibles. Por ejemplo, si en un formulario selecciona que es un Veterano, pueden aparecer áreas adicionales del formulario para proporcionar más información, pero estas áreas pueden haber estado ocultas para otros usuarios que no se interesaron por ellas. Entonces, puedes cambiar el enfoque a estos elementos después de la interacción del usuario:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, firstNewFormElement);
Lo cual cambiaría el foco al elemento proporcionado y anunciaría su etiqueta de accesibilidad.
O simplemente diles que los nuevos elementos de formulario están ahí:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, @"Veterans form elements available");
Lo cual dejaría el foco donde está, pero VoiceOver anunciaría "Veteranos forman elementos disponibles".
Nota: Este comportamiento en particular está bloqueado en mi iPad (8.1.2).
O finalmente puedes hacer esto:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
Que no hace absolutamente nada :). En serio, ni siquiera creo que a todo el framework le importe. ¡Esta línea particular de código es un desperdicio completo!
UIAccessibilityScreenChangedNotification
Un buen ejemplo de caso de uso para UIAccessibilityScreenChangedNotification
es la personalización de las situaciones de navegación con pestañas. Cuando cambia toda la pantalla, con la excepción de su área de navegación. Desea que la voz en off sepa que esencialmente cambió toda la pantalla, pero NO para enfocar el primer elemento (su primera pestaña) sino para enfocar el primer elemento de contenido.
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, firstNonGlobalNavElement);
Que reproduciría el sonido de "boop beep" y luego cambiar el foco a justo debajo de su barra de navegación global. O podrías hacer esto:
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, @"You''re on a new tab");
Que esperaría a que se cargara la nueva pestaña, reproducir el sonido "beep boop", anunciar "Estás en una nueva pestaña" en la voz en off, luego cambiar el foco al primer elemento en la pantalla y luego anunciar la etiqueta de accesibilidad para ese elemento. (¡Esto es mucho! Esto es discordante para los usuarios de lectores de pantalla. Evite este escenario, a menos que sea absolutamente necesario).
Y finalmente puedes, por supuesto, hacer esto:
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
Lo cual es equivalente a:
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, firstA11yElement);
Ambos reproducirán el sonido "beep boop", desplazarán el foco de VoiceOver al primer elemento de la pantalla y luego lo anunciarán.
Finalmente
En un comentario, alguien mencionó el almacenamiento en caché, y de vez en cuando comento en mi respuesta acerca de las cosas que pueden preocupar o no al Arsenal Backend. Si bien es posible que ocurra algo de magia de fondo, no creo en ninguna de estas circunstancias, a la parte de atrás le importa en absoluto. La razón por la que digo esto es porque:
Si alguna vez ha usado el protocolo UIAccessibilityContainer
, puede ver cómo se consulta su contenedor de vistas. No hay almacenamiento en caché. Incluso la propiedad accessibilityElementCount
recibe un pin cada vez que VoiceOver cambia el foco a un nuevo elemento de accesibilidad dentro de su contenedor. Luego pasa por el proceso de verificar en qué elemento está, pidiendo el siguiente elemento, y así sucesivamente. Está diseñado en su núcleo para manejar situaciones dinámicas. Si tuviera que insertar un nuevo elemento en su contenedor después de la interacción, aún así pasaría por todas estas consultas y estaría bien al respecto. Además, si anula las propiedades del protocolo UIAccessibility, para proporcionar pistas y etiquetas dinámicas, también puede ver que estas funciones se invocan todo el tiempo. Como tal, creo que el backend de A11y Framework recopila información ABSOLUTAMENTE CERO de estas notificaciones. La única información que VoiceOver necesita para hacer su trabajo es su Elemento de Accesibilidad actualmente enfocado, y estos elementos Contenedor de Accesibilidad. Las notificaciones están ahí para que tu aplicación sea más útil para los usuarios de VoiceOver.
¡Imagínense si este no fuera el caso cuántas veces Safari publicaría estas notificaciones! :)
Estas declaraciones particulares solo pueden ser confirmadas por alguien con conocimiento de backend del marco, que trabaja con el código, y debe verse como una conjetura. Podría ser el caso de que esto depende altamente de la versión / implementación. Definitivamente abierto a la discusión sobre estos puntos! El resto de esta publicación es bastante concreto.
Para tu referencia
La mayoría de esto proviene de la experiencia trabajando con los marcos, pero aquí hay una referencia útil si desea profundizar más.
https://developer.apple.com/documentation/uikit/accessibility/uiaccessibility
https://developer.apple.com/documentation/uikit/uiaccessibilitylayoutchangednotification
https://developer.apple.com/documentation/uikit/uiaccessibilityscreenchangednotification
Y finalmente, un repositorio de código abierto de la pequeña aplicación tonta que armé para probar todo esto.
Estoy tratando de determinar qué sucede exactamente de manera diferente cuando UIAccessibilityLayoutChangedNotification
una UIAccessibilityLayoutChangedNotification
y una UIAccessibilityScreenChangedNotification
. Por lo que puedo ver, puedo usarlos indistintamente en todas partes y no pasa nada diferente.
La documentación de Apple simplemente dice usar LayoutChanged
cuando (por ejemplo) un elemento ha sido ocultado o mostrado, y usar ScreenChanged
si toda la pantalla cambia, pero estoy interesado en lo que ELLOS hacen cuando proporciono esta información, y lo que debería ver de manera diferente cuando se usa uno u otro.
¿Alguien puede dar una explicación clara de las diferencias de implementación entre los dos?
UIAccessibilityScreenChangedNotification
indica que toda la pantalla ha cambiado y VoiceOver debe restablecerse.
UIAccessibilityLayoutChangedNotification
es para indicar que uno o más elementos, pero no todos, en la pantalla han cambiado.
cuando tu UI cambia drásticamente Por lo general, cuando un usuario se mueve a una parte diferente de su aplicación (navega a una pantalla diferente). VoiceOver notifica al usuario con un tono, borra sus cachés y hace otras preparaciones para tratar con un nuevo conjunto de datos de accesibilidad. Alerta a VoiceOver que la pantalla ha cambiado y que puede haber nuevos elementos en la pantalla para que VoiceOver reconstruya su índice de elementos de accesibilidad.
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
Si alguna parte de su IU cambia, pero el usuario no necesariamente ha saltado a una parte completamente diferente de su aplicación. (Ejemplo: en la aplicación iTunes Store, al tocar en la etiqueta de precio ($ 0.99, etc.) al lado de una canción, cambia a un botón "Comprar"). Esta notificación le dice a VoiceOver que vuelva a leer el estado actual de todos los elementos accesibles que están en pantalla, y al hacerlo se da cuenta de lo que ha cambiado e informa al usuario de esos cambios. Alerta a VoiceOver que el diseño ha cambiado y que su índice actual está desactualizado porque los elementos de la pantalla se han reordenado.
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);