Skip to content

Commit

Permalink
Add accessibility blog post
Browse files Browse the repository at this point in the history
  • Loading branch information
sberrevoets committed Oct 27, 2024
1 parent 693c2f8 commit a42e858
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 1 deletion.
82 changes: 82 additions & 0 deletions content/2017-01-18-keeping-lyft-app-accessible.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
Title: Keeping the Lyft iOS App Accessible
Date: 2017-01-18
Summary: Explanation on some strategies in how Lyft keeps its iOS app accessible

!!! note
This article was written by me but originally published on the [Lyft
Engineering Blog](https://eng.lyft.com/keeping-lyft-accessible-53155f0098b9).

At Lyft we’re in a unique position: every day we work on an app that affects
people in the real, physical world — not just the digital one. This has an
especially large impact on visually impaired users, because our app is
easier to use than the real world alternatives — navigating a train station
or queueing up at a taxi stand. Lyft aims to make a product that is
accessible and easy to use for all of our users.

## Accessibility at Lyft

If an app uses Apple’s standard controls and UI elements, it will likely already
work well with VoiceOver; however, Lyft’s UI deviates enough from standard
controls such that we don’t get that benefit out of the box. Another
complication is that many portions of the app are controlled by the server,
including a lot of the text for buttons and labels. Making these UI elements
compatible with VoiceOver often requires tweaking them manually, even if we use
native controls.

Since we try to keep all of our UI-related code in Interface Builder, and
VoiceOver is just another form of UI, we have written a simple `UIView`
extension that allows us to enable accessibility on most of our UI directly from
Interface Builder. In this extension, we add 2 properties to `UIView`:

* `accessibilitySources`: An `IBOutletCollection` of `UIView`s
* `accessibilityFormat`: a simple string that represents the format of the
accessibility label, which is subsequently passed to `String(format:)`. Every
occurrence of `%@` in this string will be replaced with the next element of
the `accessibilitySources`, and `[self]` will automatically be replaced with
the current view’s accessibilityLabel.

We can ctrl + drag UI elements into the `accessibilitySources`, and by marking
`accessibilityFormat` with `@IBInspectable` we can specify the string and the
sources all from Interface Builder, keeping the code clean and to the point.

For example, we have an accessibility format on the UILabel that displays the
selected ride mode:

![Setting the accessibility format](/images/AccessibilityFormat.png)

`[self]` is replaced by the accessibility label, which for `UILabel`s is the
text of the label itself. `%@` is replaced by an accessibility source, which we
can set up like this:

![Setting the accessibility sources](/images/AccessibilitySource.png)

By disabling the accessibility label for the subtitle, the top label’s
accessibility label will read “Selected ride mode: Line. Carpool, 2 people
maximum.” without touching any code at all.

## Changing the process

As we ramped up our VoiceOver efforts, we wanted to assess whether the changes
we made had a meaningful impact to end-users. As developers, we’re too familiar
with our own apps to make an honest call about their usability, and when it
comes to visual impairment, even a standard usability review could brush over
things that would be challenging to a blind or a visually impaired user.

This is why we’re working with a dedicated accessibility expert, himself a
native VoiceOver user, to constantly validate our work. All the feedback we’ve
been getting from VoiceOver users have further motivated our investment in
accessibility. We have optimized VoiceOver in the main flows of our app, and we
run weekly regression tests to ensure consistency and stability. Our VoiceOver
user also works directly with QA engineers, to let them know what he is looking
for and what is missing.

Over the last few months, we have made many improvements in various parts of our
app, but also in how seriously we take VoiceOver-related bugs: we block new
releases if VoiceOver users experience bugs when going through a ride. All new
features are expected to be optimized for VoiceOver from the start, and we are
working hard to optimize existing features as well.

We think of accessibility as part of the user interface, just like labels,
buttons, and text fields. By having our developers implement support for
VoiceOver as part of the initial feature, our visually impaired users will be
able to use these features as easily as our regular users.
Binary file added content/images/AccessibilityFormat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/images/AccessibilitySource.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions pelicanconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'markdown.extensions.extra': {},
'markdown.extensions.meta': {},
'markdown.extensions.toc': {},
'markdown.extensions.admonition': {},
},
'output_format': 'html5',
}
Expand Down
27 changes: 26 additions & 1 deletion theme/static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ dl#archive dd {
margin: 20px 0 20px 40px;
}


@media only screen and (max-width: 320px) {
dl#archive dd {
margin-left: 0;
Expand Down Expand Up @@ -215,6 +214,32 @@ blockquote {
color: #777;
}

.admonition {
border-left: 5px solid #4CAF50; /* Accent color for the border */
background-color: #f9f9f9; /* Light background */
padding: 15px;
margin: 20px 0;
margin-bottom: 50px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.admonition-title {
font-weight: bold;
font-size: 1.1em;
margin-bottom: 10px;
color: #333;
}

.admonition p {
margin: 0;
}

img {
max-width: 100%;
height: auto;
}

div#disqus_thread {
margin-top: 50px;
padding: 10px;
Expand Down

0 comments on commit a42e858

Please sign in to comment.