mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
[_ASDisplayViewAccessiblity] Fix accessibility in scroll views (#2079)
* Fixes issues with accessibility elements in scroll views There are two changes here: 1. Because we can't reliably update the screen positions of accessibility elements contained within a scroll view, we need to calculate them on demand, so we override the accessibilityFrame method to do that. 2. Throwing away our calculated accessibility elements on frame change seemed to cause the accessibility system to be confused. Combining these two fixes together results in success, yay! * Don't set the accessibilityFrame, getter is overridden.
This commit is contained in:
committed by
Adlai Holler
parent
05dba2263c
commit
7d21ccc184
@@ -41,11 +41,22 @@ static void SortAccessibilityElements(NSMutableArray *elements)
|
||||
[elements sortUsingComparator:comparator];
|
||||
}
|
||||
|
||||
@implementation UIAccessibilityElement (_ASDisplayView)
|
||||
@interface ASAccessibilityElement : UIAccessibilityElement
|
||||
|
||||
+ (UIAccessibilityElement *)accessibilityElementWithContainer:(id)container node:(ASDisplayNode *)node
|
||||
@property (nonatomic, strong) ASDisplayNode *node;
|
||||
@property (nonatomic, strong) ASDisplayNode *containerNode;
|
||||
|
||||
+ (ASAccessibilityElement *)accessibilityElementWithContainer:(UIView *)container node:(ASDisplayNode *)node containerNode:(ASDisplayNode *)containerNode;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASAccessibilityElement
|
||||
|
||||
+ (ASAccessibilityElement *)accessibilityElementWithContainer:(UIView *)container node:(ASDisplayNode *)node containerNode:(ASDisplayNode *)containerNode
|
||||
{
|
||||
UIAccessibilityElement *accessibilityElement = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:container];
|
||||
ASAccessibilityElement *accessibilityElement = [[ASAccessibilityElement alloc] initWithAccessibilityContainer:container];
|
||||
accessibilityElement.node = node;
|
||||
accessibilityElement.containerNode = containerNode;
|
||||
accessibilityElement.accessibilityIdentifier = node.accessibilityIdentifier;
|
||||
accessibilityElement.accessibilityLabel = node.accessibilityLabel;
|
||||
accessibilityElement.accessibilityHint = node.accessibilityHint;
|
||||
@@ -54,8 +65,14 @@ static void SortAccessibilityElements(NSMutableArray *elements)
|
||||
return accessibilityElement;
|
||||
}
|
||||
|
||||
@end
|
||||
- (CGRect)accessibilityFrame
|
||||
{
|
||||
CGRect accessibilityFrame = [self.containerNode convertRect:self.node.bounds fromNode:self.node];
|
||||
accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(accessibilityFrame, self.accessibilityContainer);
|
||||
return accessibilityFrame;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - _ASDisplayView / UIAccessibilityContainer
|
||||
|
||||
@@ -68,11 +85,7 @@ static void CollectUIAccessibilityElementsForNode(ASDisplayNode *node, ASDisplay
|
||||
// For every subnode that is layer backed or it's supernode has shouldRasterizeDescendants enabled
|
||||
// we have to create a UIAccessibilityElement as no view for this node exists
|
||||
if (currentNode != containerNode && currentNode.isAccessibilityElement) {
|
||||
UIAccessibilityElement *accessibilityElement = [UIAccessibilityElement accessibilityElementWithContainer:container node:currentNode];
|
||||
// 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 supernode
|
||||
CGRect frame = [containerNode convertRect:currentNode.bounds fromNode:currentNode];
|
||||
accessibilityElement.accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(frame, container);
|
||||
UIAccessibilityElement *accessibilityElement = [ASAccessibilityElement accessibilityElementWithContainer:container node:currentNode containerNode:containerNode];
|
||||
[elements addObject:accessibilityElement];
|
||||
}
|
||||
});
|
||||
@@ -97,10 +110,7 @@ static void CollectAccessibilityElementsForView(_ASDisplayView *view, NSMutableA
|
||||
// An accessiblityElement can either be a UIView or a UIAccessibilityElement
|
||||
if (subnode.isLayerBacked) {
|
||||
// No view for layer backed nodes exist. It's necessary to create a UIAccessibilityElement that represents this node
|
||||
UIAccessibilityElement *accessiblityElement = [UIAccessibilityElement accessibilityElementWithContainer:view node:subnode];
|
||||
|
||||
CGRect frame = [node convertRect:subnode.bounds fromNode:subnode];
|
||||
[accessiblityElement setAccessibilityFrame:UIAccessibilityConvertFrameToScreenCoordinates(frame, view)];
|
||||
UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:subnode containerNode:node];
|
||||
[elements addObject:accessiblityElement];
|
||||
} else {
|
||||
// Accessiblity element is not layer backed just add the view as accessibility element
|
||||
@@ -118,7 +128,6 @@ static void CollectAccessibilityElementsForView(_ASDisplayView *view, NSMutableA
|
||||
|
||||
@interface _ASDisplayView () {
|
||||
NSArray *_accessibleElements;
|
||||
CGRect _lastAccessibleElementsFrame;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -139,13 +148,10 @@ static void CollectAccessibilityElementsForView(_ASDisplayView *view, NSMutableA
|
||||
return @[];
|
||||
}
|
||||
|
||||
CGRect screenFrame = UIAccessibilityConvertFrameToScreenCoordinates(self.bounds, self);
|
||||
if (_accessibleElements != nil && CGRectEqualToRect(_lastAccessibleElementsFrame, screenFrame)) {
|
||||
if (_accessibleElements != nil) {
|
||||
return _accessibleElements;
|
||||
}
|
||||
|
||||
_lastAccessibleElementsFrame = screenFrame;
|
||||
|
||||
NSMutableArray *accessibleElements = [NSMutableArray array];
|
||||
CollectAccessibilityElementsForView(self, accessibleElements);
|
||||
SortAccessibilityElements(accessibleElements);
|
||||
|
||||
Reference in New Issue
Block a user