me Dan. Iʼm an iOS engineer from Japan. Itʼs almost ten thousand kilometres from Japan to here. I travelled all this way to be here with you today. Actually, this is only my second time travelling outside Japan. The rst was iOSConf SG in Singapore. To prepare for today, I started practising my English using a language-exchange app. But my English is still a work in progress. Please bear with me, and fi if we talk again, please use simple English.
Japan, I often speak at conferences. For example, I once gave a talk titled “Why are iOS buttons blue by default?” That talk sparked my interest in accessibility. Photo by fromkk
This is the demo app for this conference. We had two weeks to improve its accessibility and submit a pull request. The best pull request would win. Before I started, I asked myself one question.
as “better UX.” For developers, accessibility can mean supporting VoiceOver or making text larger. Both are examples of accessibility. But accessibility is more than that, right?
the Human Interface Guidelines. It is a great guide for making apps more accessible. In fact, the judging criteria were based on its categories. But I wanted my own de nition fi one that made sense to me. So I created this:
through.To everyone. In every situation.” An accessibility bug means that some information does not reach the user. fi This de nition made accessibility much easier for me to understand.
one of my companyʼs core values. Can you imagine how a user feels when information does not reach them? That was the key to this challenge: having a clear de nition and imagining the userʼs experience. With these two ideas, you already know 90% of how I won the award. / Maybe you can win next year! But we still have time, so letʼs look at that 90% more closely. fi For example, what if you could not tell colours apart?
not use colour to answer. We used its position. Appleʼs toggle uses more than just colour. You have used this accessible design for years without noticing it.
called “On/O Labels.” When you turn it on, symbols appear on the toggle. ff Now we have two ways to understand it: position and symbols, not just colour.
problem. But I wasnʼt sure they t the design. So I wanted to use shape to show whether it was on or o , while keeping the design clean. ff fi ff Hereʼs my answer.
Int = 2) -> some View { modifier(A11yLineLimitModifier(standard: standard, extra: extra)) } } private struct A11yLineLimitModifier: ViewModifier { @Environment(\.dynamicTypeSize) private var dynamicTypeSize let standard: Int let extra: Int } fi I created a modi er that changes the line limit. func body(content: Content) -> some View { content.lineLimit( dynamicTypeSize.isAccessibilitySize ? standard + extra : standard ) }
Int = 2) -> some View { modifier(A11yLineLimitModifier(standard: standard, extra: extra)) } } private struct A11yLineLimitModifier: ViewModifier { @Environment(\.dynamicTypeSize) private var dynamicTypeSize let standard: Int let extra: Int } func body(content: Content) -> some View { content.lineLimit( dynamicTypeSize.isAccessibilitySize ? standard + extra : standard ) } The environment gives us dynamicTypeSize. Its isAccessibilitySize property tells us if the user is using an accessibility text size. Based on that, I change the line limit from two to four.
Int = 2) -> some View { modifier(A11yLineLimitModifier(standard: standard, extra: extra)) } } private struct A11yLineLimitModifier: ViewModifier { @Environment(\.dynamicTypeSize) private var dynamicTypeSize let standard: Int let extra: Int } Now my grandma is happy too! func body(content: Content) -> some View { content.lineLimit( dynamicTypeSize.isAccessibilitySize ? standard + extra : standard ) }
{ HStack { Label(session.timeRange, systemImage: "clock") Spacer() NavigationLink(value: LocationNavigationID(value: talk.locationID)) { locationLinkLabel } } /* .. */ } } Hereʼs the original code. It uses an HStack to put a label and a navigation link side by side.
{ ViewThatFits(in: .horizontal) { HStack { Label(session.timeRange, systemImage: "clock") Spacer() NavigationLink(value: LocationNavigationID(value: talk.locationID)) { locationLinkLabel } } VStack(alignment: .leading) { Label(session.timeRange, systemImage: "clock") NavigationLink(value: LocationNavigationID(value: talk.locationID)) { locationLinkLabel } } } /* .. */ } } In this case, use ViewThatFits. It is a built-in SwiftUI view. Give it several layouts. It checks them from top to bottom and uses the rst one that ts. Put your preferred layout rst and the fallback layout second. With an "if statement”, switching branches changes the view identity, so SwiftUI creates the view again. With ViewThatFits, you donʼt need if branches. The layout system chooses for you. fi fi fi Letʼs try it!
session based on the current time. But if the text grows with Dynamic Type, the banner covers the session list behind it. So I stopped it from growing. But then my grandma canʼt read it. And I donʼt want to make my grandma cry.
{ bannerContent .accessibilityShowsLargeContentViewer { Label { VStack(alignment: .leading, spacing: 2) { Text(primaryTitleText) Text(primarySubtitleText) } } icon: { Image(systemName: iconName) } } /* .. */ } } In this case, use the Large Content Viewer. Add accessibilityShowsLargeContentViewer to the view, and provide the content you want to show. Now, press and hold it. The content appears larger in the centre of the screen.
{ bannerContent .accessibilityShowsLargeContentViewer { Label { VStack(alignment: .leading, spacing: 2) { Text(primaryTitleText) Text(primarySubtitleText) } } icon: { Image(systemName: iconName) } } /* .. */ } } My grandma is smiling again. The rule is simple: let content grow when possible. If it canʼt, / use the Large Content Viewer.
button on the speaker details screen. VoiceOver was only reading the imageʼs le name. But think about it. You already know youʼre on Dan Akiyamaʼs page. You donʼt need to hear his name again. fi You need to know where the link goes.
I hid the image from VoiceOver using accessibilityHidden. Then I gave the button the accessibility label “LinkedIn account.” My question was simple: What should someone hear when using this screen with VoiceOver?
First, listen to this. [VIDEO] When VoiceOver focus enters the map, every swipe takes you to another place. But you only want directions to the venue. Swipe̶one place. Swipe̶another place. At rst, I tried to make the map easier to use. But then I stopped and asked a simpler question: fi What does the user actually need?
the end, I let Apple Maps handle the map. For VoiceOver, I replaced all the map elements with one button: “Open in Maps.” Now the user can choose whether to open Apple Maps. Apple Maps already works well with VoiceOver. This gives the user a better experience.
is also information. Take the favourite button. If it is not a favourite, VoiceOver says, “Add to favourites.” If it is already a favourite, it says, “Remove from favourites.” So users know the current state and what the button will do. "Remove from favourite"
using a wheelchair. Just to be clear, my real grandma doesnʼt use one. Gemini added it. But this image made me think. Imagine an iPhone mounted on a wheelchair armrest. Or imagine one mounted sideways beside a bed. Many Switch Control users use xed mounts like these. They canʼt simply turn the device. Orientation also matters for people with low vision. fi Some people use landscape mode because it shows more words on each line.
I think about accessibility like this: Older devices. Di erent devices, such as iPhone, iPad, and Vision Pro maybe foldable Phone. And Slow networks. All of these are part of accessibility. Remember: “in every situation.” Take the demo appʼs map, for example. When the user is o ine, it shows a saved snapshot. MapKit has a cache, but cached data may be removed over time. The map in DemoApp rarely changes, ffl ff so saving a local copy made sense.
too. But almost no one notices. In fact, even I didnʼt notice it when I rst used the demo app. We built this screen, so we know what is tappable. But users donʼt. fi They might think, “How was I supposed to know?”
design, so users already know these patterns from other apps. They donʼt need to learn them again. Thatʼs why Apple provides the Human Interface Guidelines: to help apps stay consistent.
arrow pointing up and to the right. I also made the links / blue to show that you can tap them. Why blue? Links on the web / have been blue for many years. So we have learned that blue text is often tappable. But there is one more reason. Remember my question at the beginning of this talk? “Why are iOS buttons blue?” Hereʼs the answer.
blindness blue color blindness https://speakerdeck.com/akidon0000/nazedehuorutogaqing-se-tint-colornoli-you-nipo-ru?slide=19 This is a simulation of colour-vision-de ciency, often called colour blindness. ff fi ff ff Di erent types a ect red, green, and blue in di erent ways. This can make some colours hard to tell apart.
blindness blue color blindness https://speakerdeck.com/akidon0000/nazedehuorutogaqing-se-tint-colornoli-you-nipo-ru?slide=19 In this colour-palette, blue changes the least across these simulations.
blindness blue color blindness approx. 5.7 % approx. 1.9 % approx. 0.4 % https://www.colourblindawareness.org/colour-blindness/types-of-colour-blindness/ https://www.ucl.ac.uk/mathematical-physical-sciences/sites/mathematical̲physical̲sciences/ les/guidelines̲for̲colour̲blindness.pdf Hereʼs the data. Green-related de ciencies are the most common, followed by red. Blue-related de ciencies are rare. So blue is easier to distinguish for many users. fi fi fi This is one reason why blue became the standard colour for links.
Reduce Transparency Reduce Motion Switch Control Voice Control Full Keyboard Access 44pt Tap Targets Gesture Alternatives Haptic Feedback etc… ff Beyond Dynamic Type and VoiceOver, I made many other improvements.
Reduce Transparency Reduce Motion Switch Control Voice Control Full Keyboard Access 44pt Tap Targets Gesture Alternatives Haptic Feedback etc… For example, my grandmother and I are not good at English, so I developed Japanese language support too. ff If youʼre interested, come talk to me after the session. Iʼd be happy to chat̶slowly!
moment when information doesnʼt get through. But itʼs much easier to imagine what weʼve experienced ourselves. So̶here are three simple ways to gain that experience.
you can use it to turn on an accessibility feature. Iʼve set mine to Colour Filters. One press, and the screen turns black and white. Now I can recreate the toggle quiz anytime!
iPhones with Face ID, just triple-click the side button. On older iPhones, triple-click the Home button. Iʼve set mine to VoiceOver. After this talk, turn on VoiceOver, close your eyes, and try your own app. ff The code you write tomorrow will be di erent.
Hugh Owen C22 Great Hall, Arts Centre Next, Erica and Daniel will also talk about accessibility. If this talk made you curious, please check out their talks later.
And this really is the last thing. I'm one of the organisers of try! Swift Tokyo in Japan. Our next event will be held from next March in Tokyo. Who here thinks Japan is far away? itʼs about ten thousand kilometres away. But I travelled the same distance to be here today, so you can do it too! If youʼd like, I can also help you plan sightseeing or meetups with our japanese community. Please feel free to come and talk to me.