mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-26 05:15:49 +08:00
Text highlighting on iOS
Summary:
This diff implements highlighting of tapped text subranges for the iOS `<Text>` component, styled to match how iOS webkit views highlight links (translucent grey overlay with rounded corners).
Highlighting is enabled by default for any `<Text>` component which has an onPress handler. To disable the highlight, add `suppressHighlighting={true}` to the component props.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
{
|
||||
NSTextStorage *_textStorage;
|
||||
NSMutableArray *_reactSubviews;
|
||||
CAShapeLayer *_highlightLayer;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
@@ -78,8 +79,35 @@
|
||||
NSTextContainer *textContainer = [layoutManager.textContainers firstObject];
|
||||
CGRect textFrame = UIEdgeInsetsInsetRect(self.bounds, _contentInset);
|
||||
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
|
||||
|
||||
[layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:textFrame.origin];
|
||||
[layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:textFrame.origin];
|
||||
|
||||
__block UIBezierPath *highlightPath = nil;
|
||||
[layoutManager.textStorage enumerateAttributesInRange:glyphRange options:0 usingBlock:^(NSDictionary *attrs, NSRange range, __unused BOOL *stop){
|
||||
if ([attrs[RCTIsHighlightedAttributeName] boolValue]) {
|
||||
[layoutManager enumerateEnclosingRectsForGlyphRange:range withinSelectedGlyphRange:range inTextContainer:textContainer usingBlock:^(CGRect r, __unused BOOL *s){
|
||||
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(r, -2, -2) cornerRadius:2];
|
||||
if (highlightPath) {
|
||||
[highlightPath appendPath:path];
|
||||
} else {
|
||||
highlightPath = path;
|
||||
}
|
||||
}];
|
||||
}
|
||||
}];
|
||||
|
||||
if (highlightPath) {
|
||||
if (!_highlightLayer) {
|
||||
_highlightLayer = [CAShapeLayer layer];
|
||||
_highlightLayer.fillColor = [UIColor colorWithWhite:0 alpha:0.25].CGColor;
|
||||
[self.layer addSublayer:_highlightLayer];
|
||||
}
|
||||
_highlightLayer.path = highlightPath.CGPath;
|
||||
} else {
|
||||
[_highlightLayer removeFromSuperlayer];
|
||||
_highlightLayer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSNumber *)reactTagAtPoint:(CGPoint)point
|
||||
|
||||
Reference in New Issue
Block a user