[Accessibility] Expose and announce download progress (% complete) for VoiceOver
On iOS, when I download a book in ShelfPlayer, I can’t tell—using VoiceOver—whether the item is still downloading or finished. VoiceOver doesn’t expose any progress information (e.g., percentage), and there’s no clear completion announcement.
Summary
- Problem: Download progress is not conveyed to VoiceOver users.
- Impact: I can’t know if a book is downloading, how far along it is, or when it completes—without sighted assistance.
- Request: Provide an accessible progress indicator with a percentage (and/or transferred size) and a completion announcement.
Steps to Reproduce
- On iOS, enable VoiceOver.
- In ShelfPlayer, start downloading any book.
- Navigate to the item (library, book detail, and explore with VoiceOver.
- Notice that VoiceOver does not read a changing progress value (e.g., “Downloading — 42%”).
Actual Behavior
- VoiceOver announces something like “Downloading” or a static label, but no numeric progress is exposed.
- There’s no clear auditory announcement when the download completes.
Expected Behavior
- While downloading, VoiceOver should announce a progress value that updates (e.g., “Downloading — 42%”).
Why this matters (Accessibility impact)
For blind users, downloads without progress feedback are guesswork. A simple percentage and a completion announcement make the experience predictable and independent.
Environment
- App: ShelfPlayer — V3.0.4
- OS: iOS — V18.6.2
- Device: iPhone 15 pro (VoiceOver enabled)
Additional Context
I’m a VoiceOver user. If you need me to test a TestFlight build or share logs, I’m happy to help. I’m not sure whether a visual progress indicator is normally shown, but with VoiceOver enabled I don’t get any progress feedback, and I also couldn’t find a dedicated “Downloads” view to monitor all active downloads.
Hey, there are some VoiceOver / SwiftUI limitations I discovered while implementing VoiceOver: The accessibility value would not update properly, even if the underlying value changes. But I will look into it. How would you expect the announce functionality to work, I couldn't find a similar feature in Apple Music / Podcasts?
You can enable the offline mode from the menu in the top right hand corner on the home panel, there all downloads, including in progress ones, are shown.
Hi,
Thanks a lot for your reply!
I didn’t know that the “switch library” button actually enabled an offline mode — that’s very useful 🙂 And regarding the announce functionality, yes, in Apple Music or the App Store, VoiceOver announces the progress while downloading (like “Downloading 20%, 30%…”), so I was expecting something similar here.
Le 4 sept. 2025 à 21:30, Rasmus Krämer @.***> a écrit :
Hey, there are some VoiceOver / SwiftUI limitations I discovered while implementing VoiceOver: The accessibility value would not update properly, even if the underlying value changes. But I will look into it. How would you expect the announce functionality to work, I couldn't find a similar feature in Apple Music / Podcasts?
You can enable the offline mode from the menu in the top right hand corner on the home panel, there all downloads, including in progress ones, are shown.
Hi, Following this issue and maybe adding some insights.
Accessibility Value
ProgressView(value: progress, total: 1.0)
.accessibilityValue("\(Int(progress * 100))%")
Progress Labels
ProgressView("Loading", value: progress, total: 1.0)
.accessibilityLabel("Loading progress")
.accessibilityValue("\(Int(progress * 100))% complete")
Auto-announcing Updates
struct AccessibleProgressView: View {
@State private var progress: Double = 0.0
var body: some View {
ProgressView(value: progress, total: 1.0)
.accessibilityValue("\(Int(progress * 100))%")
.onChange(of: progress) { _, newValue in
let percentage = Int(newValue * 100)
// Announce every 10% or at completion
if percentage % 10 == 0 || percentage == 100 {
UIAccessibility.post(
notification: .announcement,
argument: "\(percentage)% complete"
)
}
}
}
}
Additional Tips
- Use
.accessibilityHint()for context about what's loading - Consider
.accessibilityRemoveTraits(.updatesFrequently)if progress updates are too frequent - For indeterminate progress:
.accessibilityLabel("Loading in progress")
I didn't know about UIAccessibility.post, I will look into adding it!