Many accessibility problems in a .NET MAUI app are easy to miss in XAML. They show up on a phone, with a screen reader on, the text size turned up, or the theme switched. Here are eight I kept running into while testing MAUI apps on Android emulators, iOS Simulators and real phones, with what to do about each.
1. AutomationId is not a name
AutomationId becomes the Android resource id and the iOS accessibilityIdentifier. It's meant for UI tests, not as a name for people. A control that only has an AutomationId has no accessible name, and screen readers handle that unpredictably: in my tests on Android, TalkBack read one such image button aloud as "btnCancelPayment", its raw id. Neither silence nor a developer id tells anyone what the button does.
<!-- No accessible name -->
<ImageButton Source="cancel.png" AutomationId="btnCancelPayment" />
<!-- A name for people, AutomationId kept for UI tests -->
<ImageButton Source="cancel.png"
AutomationId="btnCancelPayment"
SemanticProperties.Description="Cancel payment" />
And don't copy the id into the description either: "btnCancelPayment" read aloud is not a name.
2. Headings are almost never set
Screen reader users jump between headings to find their way around a page. In MAUI nothing is a heading unless you say so:
<Label Text="Payment history" SemanticProperties.HeadingLevel="Level1" />
3. Page.Title isn't an Android pane title
On Android, Page.Title shows in the toolbar, but MAUI doesn't set the accessibility pane title from it, so the page has no pane title for screen readers. Android also has a separate window title that TalkBack can announce, so whether people actually hear a title when the page changes varies. Turn TalkBack on and listen when you navigate to a new page.
4. Changing the font size on Android can send the user back to the first page
In an app built from the default template, MainActivity doesn't list FontScale in its ConfigurationChanges. When the user changes the system font size, Android recreates the activity, and the template's App.CreateWindow builds a new AppShell. The app comes back on its first page, and whatever the user was doing is gone. (Not every app loses its place; it depends on how the app restores its state.)
Adding ConfigChanges.FontScale avoids the restart, but then the text keeps its old size until the app is relaunched, unless your app re-applies its fonts itself. So it isn't a fix on its own. Test this on your most important flows: change the font size halfway through and see where you land.
5. On iOS, text may not resize until the app restarts
Before Microsoft.Maui.Controls 10.0.100, MAUI apps on iOS didn't update text while running after the system text size changed, only after the app was terminated and relaunched. It was fixed in 10.0.100 (dotnet/maui#34445).
The catch: when I created a project with dotnet new maui on SDK 10.0.300, it resolved Microsoft.Maui.Controls 10.0.20, which is before the fix. The template's package reference uses $(MauiVersion), so set it explicitly, to 10.0.100 or later:
<PropertyGroup>
<MauiVersion>10.0.100</MauiVersion>
</PropertyGroup>
Then change the text size in Settings while your app is open and check it grows. (In my tests, Shell tab bar titles on iOS didn't grow with the text size even on the fixed version.)
6. Large text can push controls off the screen
At normal size a page fits. With the font scale at 200% on a small phone, the controls at the bottom get pushed below the edge. If the page has no ScrollView, there may be no way to reach them. I saw this on a Pixel 4a (Android 13, font scale set to 2.0 over adb, since Android 13's own setting stops at 130%): the bottom buttons were cut off, swiping did nothing, and they were missing from the accessibility tree altogether.
Wrap long pages in a ScrollView, and test large text on your smallest supported device, not just the emulator.
7. Check the template's text colours
In the template styles of the MAUI version I tested, a page title came out light grey on white, around 1.7:1 contrast. WCAG 2.2's 1.4.3 Contrast (Minimum) asks for at least 4.5:1 for normal text and 3:1 for large text, so it falls short either way. Because it comes from the template, it's worth checking in your own app's styles.
8. Test both themes
Microsoft's WeatherTwentyOne sample app is a good example of why. When I scanned its first screen in dark mode, automated contrast checks found nothing. In light mode, on both an Android emulator and a Pixel 4a, the same screen had five text elements measured below WCAG 1.4.3's contrast minimum (around 2.1:1 to 2.2:1, under even the 3:1 large-text minimum). Same app, same screen, opposite results. If your app follows the system theme, check both.
How to check your own app
None of these need special tools:
- Turn on TalkBack (Android) or VoiceOver (iOS) and swipe through each screen. Does every control have a sensible name? Do pages announce a title? Can you reach everything?
- Set the system text size to the largest setting while the app is open. Does the text grow? Do you stay on the same page? Is anything cut off or unreachable? On Android 13 and earlier the largest Settings option is 130%, below the 200% WCAG 1.4.4 refers to; you can test 200% with
adb shell settings put system font_scale 2.0(and set it back with1.0). On iOS, turn on Larger Accessibility Sizes. - Switch between light and dark mode and look at the contrast again.
- Rotate the device.
Automated checks catch only some accessibility problems. Testing with the screen readers yourself, and with people who use them, is still what counts.
I found these while testing MAUI apps for accessibility. If you've run into other MAUI accessibility quirks, I'd like to hear about them in the comments.
This article was created with the help of AI. The findings come from my own tests on Android emulators, iOS Simulators and real phones (a Pixel 4a and an iPhone SE).
Top comments (0)