Move setting of accessibilityFrame into accessibleElements

- Calculate accessibilityFrame for accessibleElements already in accessibleElements method
- Remove asyncdisplaykit_node associated object as it's not needed anymore
This commit is contained in:
Michael Schneider 2016-04-09 17:03:35 -07:00
parent 1b7db082dd
commit 6a147021bc

View File

@ -21,35 +21,19 @@
+ (UIAccessibilityElement *)accessibilityElementWithContainer:(id)container node:(ASDisplayNode *)node + (UIAccessibilityElement *)accessibilityElementWithContainer:(id)container node:(ASDisplayNode *)node
{ {
UIAccessibilityElement *accessibilityElement = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:container]; UIAccessibilityElement *accessibilityElement = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:container];
accessibilityElement.asyncdisplaykit_node = node; accessibilityElement.accessibilityIdentifier = node.accessibilityIdentifier;
accessibilityElement.accessibilityLabel = node.accessibilityLabel;
accessibilityElement.accessibilityHint = node.accessibilityHint;
accessibilityElement.accessibilityValue = node.accessibilityValue;
accessibilityElement.accessibilityTraits = node.accessibilityTraits;
return accessibilityElement; return accessibilityElement;
} }
- (void)setAsyncdisplaykit_node:(ASDisplayNode *)node
{
objc_setAssociatedObject(self, @selector(asyncdisplaykit_node), node, OBJC_ASSOCIATION_ASSIGN);
self.accessibilityIdentifier = node.accessibilityIdentifier;
self.accessibilityLabel = node.accessibilityLabel;
self.accessibilityHint = node.accessibilityHint;
self.accessibilityValue = node.accessibilityValue;
self.accessibilityTraits = node.accessibilityTraits;
}
- (ASDisplayNode *)asyncdisplaykit_node
{
return objc_getAssociatedObject(self, @selector(asyncdisplaykit_node));
}
@end @end
#pragma mark - _ASDisplayView / UIAccessibilityContainer #pragma mark - _ASDisplayView / UIAccessibilityContainer
static BOOL ASNodeIsAccessiblityContainer(ASDisplayNode *node) {
return (!node.isAccessibilityElement && [node accessibilityElementCount] > 0);
}
@interface _ASDisplayView () { @interface _ASDisplayView () {
NSMutableArray *_accessibleElements; NSMutableArray *_accessibleElements;
} }
@ -71,13 +55,19 @@ static BOOL ASNodeIsAccessiblityContainer(ASDisplayNode *node) {
// Handle rasterize case // Handle rasterize case
if (selfNode.shouldRasterizeDescendants) { if (selfNode.shouldRasterizeDescendants) {
// In this case we have to go through the whole subnodes tree in BFS fashion and create all // If the node has shouldRasterizeDescendants enabled it's necessaty to go through the whole subnodes
// accessibility elements ourselves as the view hierarchy is flattened // tree of the node in BFS fashion and create for all subnodes UIAccessibilityElement objects ourselves
// as the view hierarchy is flattened
ASDisplayNodePerformBlockOnEveryNodeBFS(selfNode, ^(ASDisplayNode * _Nonnull node) { ASDisplayNodePerformBlockOnEveryNodeBFS(selfNode, ^(ASDisplayNode * _Nonnull node) {
// For every subnode we have to create a UIAccessibilityElement as we cannot just add the view to the // For every subnode we have to create a UIAccessibilityElement as we cannot just add the view to the
// accessibleElements as for a subnode of a node with shouldRasterizeDescendants enabled no view exists // accessibleElements as for a subnode of a node with shouldRasterizeDescendants enabled no view exists
if (node != selfNode && node.isAccessibilityElement) { if (node != selfNode && node.isAccessibilityElement) {
[_accessibleElements addObject:[UIAccessibilityElement accessibilityElementWithContainer:self node:node]]; UIAccessibilityElement *accessibilityElement = [UIAccessibilityElement accessibilityElementWithContainer:self node:node];
// As the node hierarchy is flattened it's necessary to convert the frame for each subnode in the tree to the
// coordinate system of the node with shouldRasterizeDescendants enabled
CGRect frame = [selfNode convertRect:node.bounds fromNode:node];
accessibilityElement.accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(frame, self);
[_accessibleElements addObject:accessibilityElement];
} }
}); });
return _accessibleElements; return _accessibleElements;
@ -87,14 +77,17 @@ static BOOL ASNodeIsAccessiblityContainer(ASDisplayNode *node) {
// Create UI accessiblity elements for each subnode that represent an elment within the accessibility container // Create UI accessiblity elements for each subnode that represent an elment within the accessibility container
for (ASDisplayNode *subnode in selfNode.subnodes) { for (ASDisplayNode *subnode in selfNode.subnodes) {
if (subnode.isAccessibilityElement) { if (subnode.isAccessibilityElement) {
id accessiblityElement = nil;
if (subnode.isLayerBacked) { if (subnode.isLayerBacked) {
// The same comment for layer backed subnodes is true as for subnodes within a shouldRasterizeDescendants node. // The same comment for layer backed nodes is true as for subnodes within a shouldRasterizeDescendants node.
// See details above // See details above
[_accessibleElements addObject:[UIAccessibilityElement accessibilityElementWithContainer:self node:subnode]]; accessiblityElement = [UIAccessibilityElement accessibilityElementWithContainer:self node:subnode];
} else { } else {
[_accessibleElements addObject:subnode.view]; accessiblityElement = subnode.view;
} }
} else if (ASNodeIsAccessiblityContainer(subnode)) { [accessiblityElement setAccessibilityFrame:UIAccessibilityConvertFrameToScreenCoordinates(subnode.frame, self)];
[_accessibleElements addObject:accessiblityElement];
} else if ([subnode accessibilityElementCount] > 0) { // Check if it's an UIAccessibilityContainer
[_accessibleElements addObject:subnode.view]; [_accessibleElements addObject:subnode.view];
} }
} }
@ -114,28 +107,7 @@ static BOOL ASNodeIsAccessiblityContainer(ASDisplayNode *node) {
return nil; return nil;
} }
UIAccessibilityElement *accessibilityElement = [_accessibleElements objectAtIndex:index]; return _accessibleElements[index];
ASDisplayNode *accessibilityElementNode = accessibilityElement.asyncdisplaykit_node;
if (accessibilityElementNode == nil) {
return nil;
}
// We have to update the accessiblity frame in accessibilityElementAtIndex: as the accessibility frame is in screen
// coordinates and between creating the accessibilityElement and returning it in accessibilityElementAtIndex:
// the frame can change
// Handle if node is rasterized
ASDisplayNode *selfNode = self.asyncdisplaykit_node;
if (selfNode.shouldRasterizeDescendants) {
// We need to convert the accessibilityElementNode frame into the coordinate system of the selfNode
CGRect frame = [selfNode convertRect:accessibilityElementNode.bounds fromNode:accessibilityElementNode];
accessibilityElement.accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(frame, self);
return accessibilityElement;
}
// Handle non rasterized case
accessibilityElement.accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(accessibilityElementNode.frame, self);
return accessibilityElement;
} }
- (NSInteger)indexOfAccessibilityElement:(id)element - (NSInteger)indexOfAccessibilityElement:(id)element