mirror of
https://github.com/status-im/react-native.git
synced 2025-01-12 10:34:57 +00:00
Implement onPress for Virtual Text nodes
Summary: When text nodes are nested, as below, `onPress` handlers need to be correctly invoked: ``` render() { return ( <Text onPress={() => console.warn('hi')}> hi <Text onPress={() => console.warn('ramanpreet')}>ramanpreet</Text> </Text> ); } ``` In the above example, clicking on "hi" should warn "hi", and clicking on "ramanpreet" should warn "ramanpreet". This diff implements that behaviour. Reviewed By: shergin Differential Revision: D9696905 fbshipit-source-id: 2daf24e76c3b3c37aa36cd1540e54876a367faf7
This commit is contained in:
parent
4c7cf13678
commit
7eb82f32a2
@ -84,4 +84,28 @@ using namespace facebook::react;
|
||||
return RCTNSStringFromString(_paragraphLocalData->getAttributedString().getString());
|
||||
}
|
||||
|
||||
@end
|
||||
- (SharedTouchEventEmitter)touchEventEmitterAtPoint:(CGPoint)point
|
||||
{
|
||||
if (!_paragraphLocalData) {
|
||||
return _eventEmitter;
|
||||
}
|
||||
|
||||
SharedTextLayoutManager textLayoutManager = _paragraphLocalData->getTextLayoutManager();
|
||||
RCTTextLayoutManager *nativeTextLayoutManager = (__bridge RCTTextLayoutManager *)textLayoutManager->getNativeTextLayoutManager();
|
||||
CGRect frame = RCTCGRectFromRect(_layoutMetrics.getContentFrame());
|
||||
|
||||
SharedShadowNode textShadowNode = [nativeTextLayoutManager getParentShadowNodeWithAttributeString:_paragraphLocalData->getAttributedString()
|
||||
paragraphAttributes:_paragraphAttributes
|
||||
frame:frame
|
||||
atPoint:point];
|
||||
|
||||
if (!textShadowNode) {
|
||||
return _eventEmitter;
|
||||
}
|
||||
|
||||
SharedEventEmitter eventEmitter = textShadowNode->getEventEmitter();
|
||||
assert(std::dynamic_pointer_cast<const TouchEventEmitter>(eventEmitter));
|
||||
return std::static_pointer_cast<const TouchEventEmitter>(eventEmitter);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -27,6 +27,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
paragraphAttributes:(facebook::react::ParagraphAttributes)paragraphAttributes
|
||||
frame:(CGRect)frame;
|
||||
|
||||
- (facebook::react::SharedShadowNode)getParentShadowNodeWithAttributeString:(facebook::react::AttributedString)attributedString
|
||||
paragraphAttributes:(facebook::react::ParagraphAttributes)paragraphAttributes
|
||||
frame:(CGRect)frame
|
||||
atPoint:(CGPoint)point;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@ -93,4 +93,30 @@ static NSLineBreakMode RCTNSLineBreakModeFromWritingDirection(EllipsizeMode elli
|
||||
return textStorage;
|
||||
}
|
||||
|
||||
- (SharedShadowNode)getParentShadowNodeWithAttributeString:(AttributedString)attributedString
|
||||
paragraphAttributes:(ParagraphAttributes)paragraphAttributes
|
||||
frame:(CGRect)frame
|
||||
atPoint:(CGPoint)point {
|
||||
NSTextStorage *textStorage =
|
||||
[self _textStorageAndLayoutManagerWithAttributesString:RCTNSAttributedStringFromAttributedString(attributedString)
|
||||
paragraphAttributes:paragraphAttributes
|
||||
size:frame.size];
|
||||
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
|
||||
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
|
||||
|
||||
CGFloat fraction;
|
||||
NSUInteger characterIndex = [layoutManager characterIndexForPoint:point
|
||||
inTextContainer:textContainer
|
||||
fractionOfDistanceBetweenInsertionPoints:&fraction];
|
||||
|
||||
// If the point is not before (fraction == 0.0) the first character and not
|
||||
// after (fraction == 1.0) the last character, then the attribute is valid.
|
||||
if (textStorage.length > 0 && (fraction > 0 || characterIndex > 0) && (fraction < 1 || characterIndex < textStorage.length - 1)) {
|
||||
RCTSharedShadowNodeWrapper *parentShadowNode = (RCTSharedShadowNodeWrapper *)[textStorage attribute:RCTAttributedStringParentShadowNode atIndex:characterIndex effectiveRange:NULL];
|
||||
return parentShadowNode.node;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
x
Reference in New Issue
Block a user