diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ef7aa4b8..43efca8efc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## master * Add your own contributions to the next release on the line below this with your name. +- [ASScrollNode] A11y support for ASScrollNode. [Max Wang](https://github.com/wsdwsd0829). [#1188](https://github.com/TextureGroup/Texture/pull/1188) - [ASDisplayNode.m] Make sure node is loaded before enter visible. [Max Wang](https://github.com/wsdwsd0829). [#886](https://github.com/TextureGroup/Texture/pull/886) - [ASTextNode2] Add improved support for all line-break modes in experimental text node. [Kevin Smith](https://github.com/wiseoldduck). [#1150](https://github.com/TextureGroup/Texture/pull/1150) - [ASExperimentalFeatures.m] Fix mismatch name in experimental features. [Max Wang](https://github.com/wsdwsd0829). [#1159](https://github.com/TextureGroup/Texture/pull/1159) diff --git a/Source/ASScrollNode.mm b/Source/ASScrollNode.mm index c155b4749b..497ef1429a 100644 --- a/Source/ASScrollNode.mm +++ b/Source/ASScrollNode.mm @@ -52,6 +52,11 @@ } } +- (NSArray *)accessibilityElements +{ + return [self.asyncdisplaykit_node accessibilityElements]; +} + @end @implementation ASScrollNode diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index a1207e9791..21ed153546 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -131,7 +131,7 @@ static void CollectUIAccessibilityElementsForNode(ASDisplayNode *node, ASDisplay }); } -static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, _ASDisplayView *view, NSMutableArray *elements) { +static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, UIView *view, NSMutableArray *elements) { UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:container containerNode:container]; NSMutableArray *labeledNodes = [[NSMutableArray alloc] init]; @@ -202,7 +202,7 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, _ } /// Collect all accessibliity elements for a given view and view node -static void CollectAccessibilityElementsForView(_ASDisplayView *view, NSMutableArray *elements) +static void CollectAccessibilityElementsForView(UIView *view, NSMutableArray *elements) { ASDisplayNodeCAssertNotNil(elements, @"Should pass in a NSMutableArray"); @@ -265,17 +265,28 @@ static void CollectAccessibilityElementsForView(_ASDisplayView *view, NSMutableA if (viewNode == nil) { return @[]; } - if (_accessibilityElements == nil) { - NSMutableArray *accessibilityElements = [[NSMutableArray alloc] init]; - CollectAccessibilityElementsForView(self, accessibilityElements); - SortAccessibilityElements(accessibilityElements); - _accessibilityElements = accessibilityElements; + _accessibilityElements = [viewNode accessibilityElements]; } - return _accessibilityElements; } @end +@implementation ASDisplayNode (AccessibilityInternal) + +- (NSArray *)accessibilityElements +{ + if (!self.isNodeLoaded) { + ASDisplayNodeFailAssert(@"Cannot access accessibilityElements since node is not loaded"); + return @[]; + } + NSMutableArray *accessibilityElements = [[NSMutableArray alloc] init]; + CollectAccessibilityElementsForView(self.view, accessibilityElements); + SortAccessibilityElements(accessibilityElements); + return accessibilityElements; +} + +@end + #endif diff --git a/Source/Private/ASDisplayNode+FrameworkPrivate.h b/Source/Private/ASDisplayNode+FrameworkPrivate.h index 2101565bf3..c8d5476b3a 100644 --- a/Source/Private/ASDisplayNode+FrameworkPrivate.h +++ b/Source/Private/ASDisplayNode+FrameworkPrivate.h @@ -312,6 +312,10 @@ __unused static NSString * _Nonnull NSStringFromASHierarchyStateChange(ASHierarc @end +@interface ASDisplayNode (AccessibilityInternal) +- (NSArray *)accessibilityElements; +@end; + @interface UIView (ASDisplayNodeInternal) @property (nullable, weak) ASDisplayNode *asyncdisplaykit_node; @end diff --git a/Tests/ASScrollNodeTests.m b/Tests/ASScrollNodeTests.m index f0d8fe2079..12c85262a8 100644 --- a/Tests/ASScrollNodeTests.m +++ b/Tests/ASScrollNodeTests.m @@ -132,4 +132,35 @@ ASXCTAssertEqualSizes(self.scrollNode.view.contentSize, subnodeSize); } +- (void)testASScrollNodeAccessibility { + ASDisplayNode *scrollNode = [[ASDisplayNode alloc] init]; + ASDisplayNode *node = [[ASDisplayNode alloc] init]; + node.isAccessibilityContainer = YES; + node.accessibilityLabel = @"node"; + [scrollNode addSubnode:node]; + node.frame = CGRectMake(0,0,100,100); + ASTextNode2 *text = [[ASTextNode2 alloc] init]; + text.attributedText = [[NSAttributedString alloc] initWithString:@"text"]; + [node addSubnode:text]; + + ASTextNode2 *text2 = [[ASTextNode2 alloc] init]; + text2.attributedText = [[NSAttributedString alloc] initWithString:@"text2"]; + [node addSubnode:text2]; + __unused UIView *view = scrollNode.view; + XCTAssertTrue(node.view.accessibilityElements.firstObject, @"node"); + + // Following tests will only pass when accessibility is enabled. + // More details: https://github.com/TextureGroup/Texture/pull/1188 + + // A bunch of a11y containers each of which hold aggregated labels. + /* NSArray *a11yElements = [scrollNode.view accessibilityElements]; + XCTAssertTrue(a11yElements.count > 0, @"accessibilityElements should exist"); + + UIAccessibilityElement *container = a11yElements.firstObject; + XCTAssertTrue(container.isAccessibilityElement == false && container.accessibilityElements.count > 0); + UIAccessibilityElement *ae = container.accessibilityElements.firstObject; + XCTAssertTrue([[ae accessibilityLabel] isEqualToString:@"node, text, text2"]); + */ +} + @end