From 9db065a09e22a98184e739383af049ac5303b79d Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Wed, 10 Sep 2025 15:08:11 +0200 Subject: [PATCH] iOS: Fix a11y representation of RadioButton and CheckBox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RadioButton and CheckBox should not provide a value because this leads to the behavior that iOS read out both states (checked and unchecked). Also we need to provide own strings in multiple languages because resolving 0 and 1 is not supported by iOS in this case. This behavior is not intended by iOS. Instead we need to provide the state with a UIAccessibilityTrait. This creates the same representation as for the items in the iOS settings and uses the iOS specific wording. Task-number: QTBUG-139676 Pick-to: 6.9 6.8 Change-Id: I1369291cc9e8fbbe9ae65f2ca6c742d942d2acd6 Reviewed-by: Tor Arne Vestbø (cherry picked from commit e9da800428045f3dc4542f8767bb4b3335a3df48) Reviewed-by: Qt Cherry-pick Bot --- src/plugins/platforms/ios/quiaccessibilityelement.mm | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.mm b/src/plugins/platforms/ios/quiaccessibilityelement.mm index d228f090438..49fd08d945d 100644 --- a/src/plugins/platforms/ios/quiaccessibilityelement.mm +++ b/src/plugins/platforms/ios/quiaccessibilityelement.mm @@ -109,10 +109,15 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAccessibilityElement); QAccessible::State state = iface->state(); - if (state.checkable) + if (state.checkable) { + if (iface->role() == QAccessible::CheckBox + || iface->role() == QAccessible::RadioButton) + return @""; + return state.checked ? QCoreApplication::translate(ACCESSIBILITY_ELEMENT, AE_CHECKED).toNSString() : QCoreApplication::translate(ACCESSIBILITY_ELEMENT, AE_UNCHECKED).toNSString(); + } QAccessibleValueInterface *val = iface->valueInterface(); if (val) { @@ -159,6 +164,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAccessibilityElement); const auto accessibleRole = iface->role(); if (accessibleRole == QAccessible::Button) { traits |= UIAccessibilityTraitButton; + } else if (accessibleRole == QAccessible::CheckBox + || accessibleRole == QAccessible::RadioButton) { + if (state.checked) + traits |= UIAccessibilityTraitSelected; } else if (accessibleRole == QAccessible::EditableText) { static auto defaultTextFieldTraits = []{ auto *textField = [[[UITextField alloc] initWithFrame:CGRectZero] autorelease];