Add getRectWithAttributedString() to RCTTextLayoutManager

Summary:
Changelog:
[iOS][Added] - `getRectWithAttributedString()` aims to get the rect of the fragment with embedded link, which is necessary when building the `accessibilityElement`. In this function, we first enumerate attributedString to find the range of fragments whose `accessibilityRole` is @"link". Then we calculate the rect of the fragment and send to the block and we would define what to do in the block in `RCTParagraphComponentAccessibilityProvider`.

Reviewed By: shergin

Differential Revision: D22286733

fbshipit-source-id: 4d11cb54375a4e9e72869e646fcb484de089b14b
This commit is contained in:
Jiayan Zhuang
2020-07-06 14:58:38 -07:00
committed by Facebook GitHub Bot
parent 10a800da25
commit 96708d58e4
2 changed files with 53 additions and 0 deletions
@@ -15,6 +15,13 @@
NS_ASSUME_NONNULL_BEGIN
/**
@abstract Enumeration block for text fragments.
*/
using RCTTextLayoutFragmentEnumerationBlock =
void (^)(CGRect fragmentRect, NSString *_Nonnull fragmentText, NSString *value);
/**
* iOS-specific TextLayoutManager
*/
@@ -38,6 +45,12 @@ NS_ASSUME_NONNULL_BEGIN
frame:(CGRect)frame
atPoint:(CGPoint)point;
- (void)getRectWithAttributedString:(facebook::react::AttributedString)attributedString
paragraphAttributes:(facebook::react::ParagraphAttributes)paragraphAttributes
enumerateAttribute:(NSString *)enumerateAttribute
frame:(CGRect)frame
usingBlock:(RCTTextLayoutFragmentEnumerationBlock)block;
@end
NS_ASSUME_NONNULL_END
@@ -182,4 +182,44 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
return unwrapManagedObject(sharedNSAttributedString);
}
- (void)getRectWithAttributedString:(AttributedString)attributedString
paragraphAttributes:(ParagraphAttributes)paragraphAttributes
enumerateAttribute:(NSString *)enumerateAttribute
frame:(CGRect)frame
usingBlock:(RCTTextLayoutFragmentEnumerationBlock)block
{
NSTextStorage *textStorage = [self
_textStorageAndLayoutManagerWithAttributesString:[self _nsAttributedStringFromAttributedString:attributedString]
paragraphAttributes:paragraphAttributes
size:frame.size];
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
[layoutManager ensureLayoutForTextContainer:textContainer];
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
[textStorage enumerateAttribute:enumerateAttribute
inRange:characterRange
options:0
usingBlock:^(NSString *value, NSRange range, BOOL *pause) {
if (!value) {
return;
}
[layoutManager
enumerateEnclosingRectsForGlyphRange:range
withinSelectedGlyphRange:range
inTextContainer:textContainer
usingBlock:^(CGRect enclosingRect, BOOL *_Nonnull stop) {
block(
enclosingRect,
[textStorage attributedSubstringFromRange:range].string,
value);
*stop = YES;
}];
}];
}
@end