From e3391ffc53bcd9076797868512fb360e766a4298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20=C5=9Aredzi=C5=84ski?= Date: Tue, 25 Jun 2024 14:37:03 +0200 Subject: [PATCH] Allow UIView subviews to be a part of Accessibility Tree --- Source/Details/_ASDisplayViewAccessiblity.mm | 35 ++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index 23b1f89db..d100982ed 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -220,6 +220,11 @@ static BOOL nodeIsHiddenFromAcessibility(ASDisplayNode *node) { return node.isHidden || node.alpha == 0.0 || node.accessibilityElementsHidden; } +/// returns YES if this view should be considered "hidden" from the screen reader. +static BOOL viewIsHiddenFromAcessibility(UIView *view) { + return view.isHidden || view.alpha == 0.0 || view.accessibilityElementsHidden; +} + /// Collect all accessibliity elements for a given view and view node static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *elements) { @@ -302,6 +307,36 @@ static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *el [elements addObject:subnode.view]; } } + + if (modalSubnode) { + return; + } + + NSArray *subviews = view.subviews; + for (UIView *subview in subviews) { + // If a view is is already added then skip it + if ([elements containsObject:subview]) { + continue; + } + + // If a view is hidden or has an alpha of 0.0 we should not include it + if (viewIsHiddenFromAcessibility(subview)) { + continue; + } + + // If a subview is outside of the view's window, exclude it UNLESS it is a subview of an UIScrollView. + // In this case UIKit will return the element even if it is outside of the window or the scrollView's visible rect (contentOffset + contentSize) + CGRect viewInWindowCoords = [node convertRect:subview.frame toNode:nil]; + if (!CGRectIntersectsRect(view.window.frame, viewInWindowCoords) && !recusivelyCheckSuperviewsForScrollView(view)) { + continue; + } + + if (subview.isAccessibilityElement) { + [elements addObject:subview]; + } else if (subview.accessibilityElementCount > 0) { + [elements addObject:subview]; + } + } } @implementation _ASDisplayView (UIAccessibilityContainer)