diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm index 8becf81fcf757a..b5e5f3c5c590ab 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm @@ -29,15 +29,13 @@ using namespace facebook::react; +#if !TARGET_OS_OSX // [macOS] // ParagraphTextView is an auxiliary view we set as contentView so the drawing // can happen on top of the layers manipulated by RCTViewComponentView (the parent view) -// [macOS -// On macOS, we defer drawing to an NSTextView rather than a plan NSView, in order -// to get more native behaviors like text selection. -// macOS] -#if !TARGET_OS_OSX // [macOS] @interface RCTParagraphTextView : RCTUIView // [macOS] #else // [macOS +// On macOS, we also defer drawing to an NSTextView, +// in order to get more native behaviors like text selection. @interface RCTParagraphTextView : NSTextView // [macOS] #endif // macOS] @@ -45,6 +43,11 @@ @interface RCTParagraphTextView : NSTextView // [macOS] @property (nonatomic) ParagraphAttributes paragraphAttributes; @property (nonatomic) LayoutMetrics layoutMetrics; +#if TARGET_OS_OSX // [macOS] +/// UIKit compatibility shim that simply calls `[self setNeedsDisplay:YES]` +- (void)setNeedsDisplay; +#endif + @end #if !TARGET_OS_OSX // [macOS] @@ -161,13 +164,9 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & - (void)updateState:(const State::Shared &)state oldState:(const State::Shared &)oldState { _state = std::static_pointer_cast(state); -#if !TARGET_OS_OSX // [macOS] _textView.state = _state; [_textView setNeedsDisplay]; [self setNeedsLayout]; -#else // [macOS - [self _updateTextView]; -#endif // macOS] } - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics @@ -177,52 +176,9 @@ - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics // re-applying individual sub-values which weren't changed. [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:_layoutMetrics]; _textView.layoutMetrics = _layoutMetrics; -#if !TARGET_OS_OSX // [macOS] [_textView setNeedsDisplay]; [self setNeedsLayout]; -#else // [macOS - [self _updateTextView]; -#endif // macOS] -} - -#if TARGET_OS_OSX // [macOS -- (void)_updateTextView -{ - if (!_state) { - return; - } - - auto textLayoutManager = _state->getData().layoutManager.lock(); - - if (!textLayoutManager) { - return; - } - - RCTTextLayoutManager *nativeTextLayoutManager = - (RCTTextLayoutManager *)unwrapManagedObject(textLayoutManager->getNativeTextLayoutManager()); - - CGRect frame = RCTCGRectFromRect(_layoutMetrics.getContentFrame()); - - NSTextStorage *textStorage = [nativeTextLayoutManager getTextStorageForAttributedString:_state->getData().attributedString paragraphAttributes:_paragraphAttributes size:frame.size]; - - NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject; - NSTextContainer *textContainer = layoutManager.textContainers.firstObject; - - [_textView replaceTextContainer:textContainer]; - - NSArray *managers = [[textStorage layoutManagers] copy]; - for (NSLayoutManager *manager in managers) { - [textStorage removeLayoutManager:manager]; - } - - _textView.minSize = frame.size; - _textView.maxSize = frame.size; - _textView.frame = frame; - _textView.textStorage.attributedString = textStorage; - - [self setNeedsDisplay]; } -#endif // macOS] - (void)prepareForRecycle { @@ -425,11 +381,13 @@ - (void)copy:(id)sender return RCTParagraphComponentView.class; } -#if !TARGET_OS_OSX // [macOS] @implementation RCTParagraphTextView { +#if !TARGET_OS_OSX // [macOS] CAShapeLayer *_highlightLayer; +#endif // macOS] } + - (void)drawRect:(CGRect)rect { if (!_state) { @@ -447,6 +405,7 @@ - (void)drawRect:(CGRect)rect CGRect frame = RCTCGRectFromRect(_layoutMetrics.getContentFrame()); +#if !TARGET_OS_OSX // [macOS] [nativeTextLayoutManager drawAttributedString:_state->getData().attributedString paragraphAttributes:_paragraphAttributes frame:frame @@ -464,11 +423,33 @@ - (void)drawRect:(CGRect)rect self->_highlightLayer = nil; } }]; +#else // [macOS + NSTextStorage *textStorage = [nativeTextLayoutManager getTextStorageForAttributedString:_state->getData().attributedString paragraphAttributes:_paragraphAttributes size:frame.size]; + + NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject; + NSTextContainer *textContainer = layoutManager.textContainers.firstObject; + + [self replaceTextContainer:textContainer]; + + NSArray *managers = [[textStorage layoutManagers] copy]; + for (NSLayoutManager *manager in managers) { + [textStorage removeLayoutManager:manager]; + } + + self.minSize = frame.size; + self.maxSize = frame.size; + self.frame = frame; + [[self textStorage] setAttributedString:textStorage]; + + [super drawRect:rect]; +#endif } -@end -#else // [macOS -@implementation RCTParagraphTextView +#if TARGET_OS_OSX // [macOS +- (void)setNeedsDisplay +{ + [self setNeedsDisplay:YES]; +} - (BOOL)canBecomeKeyView { @@ -484,6 +465,6 @@ - (BOOL)resignFirstResponder return [super resignFirstResponder]; } +#endif // macOS] @end -#endif // macOS]