mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
add support for text highlighting (#43386)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43386 Changes: - fixes `RCTAttributedTextUtils` to set `RCTAttributedStringIsHighlightedAttributeName` attribute according to `isHighlighted` textAttribute value. - adds block to `drawAttributedString` and passed highlighted bezier curve to it. - updates `drawRect` to visually highlight selected text. ## Changelog: [iOS][Fixed] - Fixed text highlighting in the New Architecture Reviewed By: sammy-SC Differential Revision: D54594472 fbshipit-source-id: ed454e3a1660fa76d96cb131e33fba1c05f47776
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7bb204a160
commit
eadcebbb3e
+16
-1
@@ -35,6 +35,7 @@ using namespace facebook::react;
|
||||
ParagraphAttributes _paragraphAttributes;
|
||||
RCTParagraphComponentAccessibilityProvider *_accessibilityProvider;
|
||||
UILongPressGestureRecognizer *_longPressGestureRecognizer;
|
||||
CAShapeLayer *_highlightLayer;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
@@ -132,7 +133,21 @@ using namespace facebook::react;
|
||||
[nativeTextLayoutManager drawAttributedString:_state->getData().attributedString
|
||||
paragraphAttributes:_paragraphAttributes
|
||||
frame:frame
|
||||
textStorage:unwrapManagedObject(nsTextStorage)];
|
||||
textStorage:unwrapManagedObject(nsTextStorage)
|
||||
drawHighlightPath:^(UIBezierPath *highlightPath) {
|
||||
if (highlightPath) {
|
||||
if (!self->_highlightLayer) {
|
||||
self->_highlightLayer = [CAShapeLayer layer];
|
||||
self->_highlightLayer.fillColor = [UIColor colorWithWhite:0 alpha:0.25].CGColor;
|
||||
[self.layer addSublayer:self->_highlightLayer];
|
||||
}
|
||||
self->_highlightLayer.position = frame.origin;
|
||||
self->_highlightLayer.path = highlightPath.CGPath;
|
||||
} else {
|
||||
[self->_highlightLayer removeFromSuperlayer];
|
||||
self->_highlightLayer = nil;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Accessibility
|
||||
|
||||
+1
-1
@@ -285,7 +285,7 @@ NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(c
|
||||
}
|
||||
|
||||
// Special
|
||||
if (textAttributes.isHighlighted) {
|
||||
if (textAttributes.isHighlighted.value_or(false)) {
|
||||
attributes[RCTAttributedStringIsHighlightedAttributeName] = @YES;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -43,7 +43,8 @@ using RCTTextLayoutFragmentEnumerationBlock =
|
||||
- (void)drawAttributedString:(facebook::react::AttributedString)attributedString
|
||||
paragraphAttributes:(facebook::react::ParagraphAttributes)paragraphAttributes
|
||||
frame:(CGRect)frame
|
||||
textStorage:(NSTextStorage *_Nullable)textStorage;
|
||||
textStorage:(NSTextStorage *_Nullable)textStorage
|
||||
drawHighlightPath:(void (^_Nullable)(UIBezierPath *highlightPath))block;
|
||||
|
||||
- (facebook::react::LinesMeasurements)getLinesForAttributedString:(facebook::react::AttributedString)attributedString
|
||||
paragraphAttributes:
|
||||
|
||||
+33
@@ -76,6 +76,7 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
|
||||
paragraphAttributes:(ParagraphAttributes)paragraphAttributes
|
||||
frame:(CGRect)frame
|
||||
textStorage:(NSTextStorage *_Nullable)textStorage
|
||||
drawHighlightPath:(void (^_Nullable)(UIBezierPath *highlightPath))block
|
||||
{
|
||||
BOOL createdStorageForFrame = NO;
|
||||
|
||||
@@ -118,6 +119,38 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
|
||||
#if TARGET_OS_MACCATALYST
|
||||
CGContextRestoreGState(context);
|
||||
#endif
|
||||
|
||||
if (block != nil) {
|
||||
__block UIBezierPath *highlightPath = nil;
|
||||
NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
|
||||
|
||||
[textStorage
|
||||
enumerateAttribute:RCTAttributedStringIsHighlightedAttributeName
|
||||
inRange:characterRange
|
||||
options:0
|
||||
usingBlock:^(NSNumber *value, NSRange range, __unused BOOL *stop) {
|
||||
if (!value.boolValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
[layoutManager
|
||||
enumerateEnclosingRectsForGlyphRange:range
|
||||
withinSelectedGlyphRange:range
|
||||
inTextContainer:textContainer
|
||||
usingBlock:^(CGRect enclosingRect, __unused BOOL *anotherStop) {
|
||||
UIBezierPath *path = [UIBezierPath
|
||||
bezierPathWithRoundedRect:CGRectInset(enclosingRect, -2, -2)
|
||||
cornerRadius:2];
|
||||
if (highlightPath) {
|
||||
[highlightPath appendPath:path];
|
||||
} else {
|
||||
highlightPath = path;
|
||||
}
|
||||
}];
|
||||
}];
|
||||
|
||||
block(highlightPath);
|
||||
}
|
||||
}
|
||||
|
||||
- (LinesMeasurements)getLinesForAttributedString:(AttributedString)attributedString
|
||||
|
||||
Reference in New Issue
Block a user