Skip to content

Commit

Permalink
Move updateTextView logic to drawText
Browse files Browse the repository at this point in the history
  • Loading branch information
Saadnajmi committed Nov 19, 2024
1 parent 5a9f916 commit ae96a29
Showing 1 changed file with 39 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,25 @@

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]

@property (nonatomic) ParagraphShadowNode::ConcreteState::Shared state;
@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]
Expand Down Expand Up @@ -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<const ParagraphShadowNode::ConcreteState>(state);
#if !TARGET_OS_OSX // [macOS]
_textView.state = _state;
[_textView setNeedsDisplay];
[self setNeedsLayout];
#else // [macOS
[self _updateTextView];
#endif // macOS]
}

- (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
Expand All @@ -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<NSLayoutManager *> *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
{
Expand Down Expand Up @@ -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) {
Expand All @@ -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
Expand All @@ -464,11 +423,34 @@ - (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<NSLayoutManager *> *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
{
Expand All @@ -484,6 +466,6 @@ - (BOOL)resignFirstResponder

return [super resignFirstResponder];
}
#endif // macOS]

@end
#endif // macOS]

0 comments on commit ae96a29

Please sign in to comment.