diff --git a/en/mobile/ios/development/index.html b/en/mobile/ios/development/index.html index dde32c171..566785432 100644 --- a/en/mobile/ios/development/index.html +++ b/en/mobile/ios/development/index.html @@ -1360,7 +1360,7 @@
+ Text("Some small text needing bigger focus area")
+ .border(Color.red)
+ .padding()
+ // The overlay does the trick
+ .overlay(
+ Rectangle()
+ // Adjust the lineWidth to expand the hit area
+ .stroke(Color.clear, lineWidth: 20)
+ // Negative padding to expand the hit area
+ .padding(-20)
+ )
+ .border(Color.blue)
+ .accessibilityElement()
+
Example 3 : B1.1
view as modal.
In this case, parent A
and B2
(or possibly their subviews) are vocalized with the modal view: only B1.2
isn't read out by VoiceOver because it's B1.1
sibling.
+ // Parent A
+ VStack {
+ Text("A1")
+ Text("A2")
+ Text("A3")
+ }.background(Color.green)
+
+ // Parent B
+ VStack {
+ // B1
+ HStack {
+ Text("B1.1").accessibilityAddTraits(.isModal)
+ Text("B1.2")
+ }.background(Color.orange)
+ // B2
+ VStack {
+ Text("B2.1")
+ Text("B2.2")
+ Text("B2.3")
+ }.background(Color.yellow)
+ }.background(Color.red)
+
+ /*
+ By default in SwiftUI, views parent A and parent B are not accessible and hidden,
+ no need to hide like with UIKit.
+ Do not forget to remove the trait when needed otherwise no iteration will be done.
+ */
+
+
var body: some View {
Text("Some text")
// System font
@@ -2486,7 +2559,8 @@ Truncation hyphen
-
The rationale behind is the use of a NSMutableAttributedString
with a NSMutableParagraphStyle
type property as exposed hereunder:
+
The rationale behind is the use of a NSMutableAttributedString
with a NSMutableParagraphStyle
type property as exposed hereunder:
+However, these APIs are not yet available with SwiftUI at the time of writing ; it is therefore necessary to approach the problem differently.
+ Image(systemName: "hand.thumbsup")
+ .accessibilityShowsLargeContentViewer {
+ Label("logo", systemImage: "hand.thumbsup")
+ }
+
In the same way, on a clickable element like a button whose magnification may become problematic, it's quite possible to use this feature to display its content and to ensure to trigger its actions when the finger is up:
@@ -2765,9 +2930,20 @@
+ Button {
+ // Action will be triggered when the button will be released
+ } label: {
+ Image(systemName: "hand.thumbsup")
+ }
+ .accessibilityShowsLargeContentViewer {
+ Label("logo", systemImage: "hand.thumbsup")
+ }
+
When the long press gesture is already implemented on the graphical element, it may be interesting to use the gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
method that will be helpful to set up the two gestures simutaneously.
With UIKit, the long press gesture is already implemented on the graphical element, it may be interesting to use the gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
method that will be helpful to set up the two gestures simutaneously.
+With SwiftUI, you will have to use the Gestures API.
@@ -3154,6 +3330,21 @@ Custom actions
+ var body: some View {
+ Text("A view with custom actions")
+ .accessibilityElement()
+ .accessibilityAction(named: "options") {
+ print("Action OPTIONS selected")
+ }
+ .accessibilityAction(named: "flag") {
+ print("Action FLAG selected")
+ }
+ .accessibilityAction(named: "trash") {
+ print("Action TRASH selected")
+ }
+ }
+
The code above gives rise to a smoother result thanks to consecutive flicks on the selected accessible element:
@@ -3319,6 +3510,7 @@
However, if the selected element is adjustable or holds any custom actions, its actions will prevail over those of the rotor.
Such a feature must be implemented with caution and according to specific needs whose only purpose should be to improve and facilitate the user experience.
+These examples are only valid for UIKit. Indeed, the Swift API at the time of writing these lines is not isofunctional with the UIKit API. Thus it is not possible to have an example where a view is updated by swiping up or down the finger on the rotor. However, it is possible to define a rotor in SwiftUI with the 'accessibilityRotor' and AccessibilityRotorEntry methods.
The visual rendering is exposed hereunder:
diff --git a/fr/mobile/ios/developpement/index.html b/fr/mobile/ios/developpement/index.html
index 4f9cce7d0..fc5b350dd 100644
--- a/fr/mobile/ios/developpement/index.html
+++ b/fr/mobile/ios/developpement/index.html
@@ -913,9 +913,6 @@
-
@@ -983,9 +980,6 @@
-
+ Text("Simple text ayant besoin d'une zone de focus Voice Over plus grande")
+ .border(Color.red)
+ .padding()
+ // Ajouter un overlay va permettre d'aggrandir la zone
+ .overlay(
+ Rectangle()
+ // On aggrandit ainsi la zone
+ .stroke(Color.clear, lineWidth: 20)
+ // Une autre manière d'aggrandir la zone
+ .padding(-20)
+ )
+ .border(Color.blue)
+ .accessibilityElement()
+
Exemple 3 : passer B1.1
en vue modale.
Dans ce cas, les vues parent A
et B2
(ou éventuellement leurs sous-vues) sont vocalisées tout comme la vue modale.
@@ -2249,6 +2287,35 @@
+ // Parent A
+ VStack {
+ Text("A1")
+ Text("A2")
+ Text("A3")
+ }.background(Color.green)
+
+ // Parent B
+ VStack {
+ // B1
+ HStack {
+ Text("B1.1").accessibilityAddTraits(.isModal)
+ Text("B1.2")
+ }.background(Color.orange)
+ // B2
+ VStack {
+ Text("B2.1")
+ Text("B2.2")
+ Text("B2.3")
+ }.background(Color.yellow)
+ }.background(Color.red)
+
+ /*
+ Par défaut SwiftUI, les vues parents A et B ne sont pas accessible et sont cachées de Voice Over,
+ la logique est différente de celle de l'implémentation UIKit.
+ Ne pas oublier par la suite de retirer le trait donné si besoin.
+ */
+
var body: some View {
Text("Un peu de texte")
// Police système
@@ -2521,7 +2588,8 @@ Trait d'union de troncature
-
L'idée est de spécifier l'utilisation d'un NSMutableAttributedString
auquel on ajoute une propriété de type NSMutableParagraphStyle
comme indiqué par l'exemple ci-dessous :
+
Avec UIKit, l'idée est de spécifier l'utilisation d'un NSMutableAttributedString
auquel on ajoute une propriété de type NSMutableParagraphStyle
comme indiqué par l'exemple ci-dessous.
+Toutefois, ces API ne sont pas encore disponibles avec SwiftUI à l'heure où ces lignes sont écrites ; il convient donc d'aborder le problème différement.
Si le grossissement extrême d'un élément graphique risque de dégrader l'expérience utilisateur, on peut très simplement implémenter le Large
Content
Viewer
sur cette vue pour obtenir le résultat grossi an milieu d'écran :
Si le grossissement extrême d'un élément graphique risque de dégrader l'expérience utilisateur, on peut très simplement implémenter le Large
Content
Viewer
sur cette vue pour obtenir le résultat grossi eu milieu d'écran :
@@ -2752,6 +2905,12 @@ Large Content Viewer
+
+ Image(systemName: "hand.thumbsup")
+ .accessibilityShowsLargeContentViewer {
+ Label("logo", systemImage: "hand.thumbsup")
+ }
+
De la même façon, pour un élément cliquable comme un bouton dont le grossissement pourrait devenir problématique, il est tout à fait possible d'utiliser cette fonctionnalité pour afficher son contenu et s'assurer que son action sera déclenchée dès que le doigt sera relevé :
@@ -2802,9 +2961,20 @@
+ Button {
+ // L'action sera déclenchée quand le bouton sera relaché
+ } label: {
+ Image(systemName: "hand.thumbsup")
+ }
+ .accessibilityShowsLargeContentViewer {
+ Label("logo", systemImage: "hand.thumbsup")
+ }
+
Lorsque la gestuelle 'appui long' est déjà implémentée sur l'élément impacté, il est nécessaire d'utiliser la méthode gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
qui permettra de mettre en place concomitamment les deux gestuelles.
Avec UIKit, lorsque la gestuelle 'appui long' est déjà implémentée sur l'élément impacté, il est nécessaire d'utiliser la méthode gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
qui permettra de mettre en place concomitamment les deux gestuelles.
+Pour SwftUI, il faudra se tourner vers l'API Gestures.
@@ -3233,6 +3403,21 @@ Actions personnalisées
+
+ var body: some View {
+ Text("Une vue avec des actions personnalisées")
+ .accessibilityElement()
+ .accessibilityAction(named: "options") {
+ print("Action OPTIONS sélectionnée")
+ }
+ .accessibilityAction(named: "drapeau") {
+ print("Action DRAPEAU sélectionnée")
+ }
+ .accessibilityAction(named: "corbeille") {
+ print("Action CORBEILLE sélectionnée")
+ }
+ }
+
Le code implémenté ci-dessus permet d'obtenir le résultat suivant par balayages successifs sur l'élément accessible sélectionné :
@@ -3397,6 +3582,8 @@
accessibilityRotor
et AccessibilityRotorEntry.
Le rendu de ce code est visualisable ci-dessous :