Skip to content
This repository has been archived by the owner on May 24, 2024. It is now read-only.

Fix NIAttributedLabel accessibilityFrame for animations #597

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 39 additions & 4 deletions src/attributedlabel/src/NIAttributedLabel.m
Expand Up @@ -94,6 +94,41 @@ CGSize NISizeOfAttributedStringConstrainedToSize(NSAttributedString* attributedS
return CGSizeMake(NICGFloatCeil(newSize.width), NICGFloatCeil(newSize.height));
}

/**
* @internal
*
* The NIViewAccessibilityElement class encapsulates information about an item
* that should be accessible to users with disabilities, but isn't accessible
* by default and might be used in animations.
*
* Differences between UIAccessibilityElement and NIViewAccessibilityElement:
*
* - The accessibilityContainer must be a UIView.
* - The accessibilityFrame is recomputed every time from the frameInContainer
* and the accessibilityContainer.
*/
@interface NIViewAccessibilityElement : UIAccessibilityElement

// This frame is in the accessibilityContainer coordinates.
@property (nonatomic) CGRect frameInContainer;

@end

@implementation NIViewAccessibilityElement

- (instancetype)initWithAccessibilityContainer:(id)container {
NIDASSERT([container isKindOfClass:[UIView class]]);
return [super initWithAccessibilityContainer:container];
}

- (CGRect)accessibilityFrame {
UIView* view = [self accessibilityContainer];
CGRect frame = [view convertRect:self.frameInContainer toView:nil];
return [view.window convertRect:frame toWindow:nil];
}

@end

@interface NIAttributedLabelImage : NSObject

- (CGSize)boxSize; // imageSize + margins
Expand Down Expand Up @@ -1400,19 +1435,19 @@ - (NSArray *)accessibleElements {

NSString* label = [self.mutableAttributedString.string substringWithRange:result.range];
for (NSValue* rectValue in rectsForLink) {
UIAccessibilityElement* element = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self];
NIViewAccessibilityElement* element = [[NIViewAccessibilityElement alloc] initWithAccessibilityContainer:self];
element.accessibilityLabel = label;
element.accessibilityFrame = [self convertRect:rectValue.CGRectValue toView:self.window];
element.frameInContainer = rectValue.CGRectValue;
element.accessibilityTraits = UIAccessibilityTraitLink;
[accessibleElements addObject:element];
}
}

// Add this label's text as the "bottom-most" accessibility element, i.e. the last element in the
// array. This gives link priorities.
UIAccessibilityElement* element = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self];
NIViewAccessibilityElement* element = [[NIViewAccessibilityElement alloc] initWithAccessibilityContainer:self];
element.accessibilityLabel = self.attributedText.string;
element.accessibilityFrame = [self convertRect:self.bounds toView:self.window];
element.frameInContainer = self.bounds;
element.accessibilityTraits = UIAccessibilityTraitNone;
[accessibleElements addObject:element];

Expand Down