Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 2713bdd

Browse files
author
Scott Goodson
committed
[ASTextNode, ASDisplayNode] Create -calculatedLayoutDidChange and use it in text node.
This allows the change in size for the NSTextContainer to occur off the main thread, whenever that size change is necessary. Then the text relayout can occur earlier, during the process of computing ASLayoutSpecs.
1 parent d708874 commit 2713bdd

3 files changed

Lines changed: 41 additions & 14 deletions

File tree

AsyncDisplayKit/ASDisplayNode+Subclasses.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ NS_ASSUME_NONNULL_BEGIN
9191
*/
9292
- (void)layoutDidFinish;
9393

94+
/**
95+
* @abstract Called on a background thread if !isNodeLoaded - called on the main thread if isNodeLoaded.
96+
*
97+
* @discussion When the .calculatedLayout property is set to a new ASLayout (directly from -calculateLayoutThatFits: or
98+
* calculated via use of -layoutSpecThatFits:), subclasses may inspect it here.
99+
*/
100+
- (void)calculatedLayoutDidChange;
94101

95102
/** @name Layout calculation */
96103

AsyncDisplayKit/ASDisplayNode.mm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ - (ASLayout *)__measureWithSizeRange:(ASSizeRange)constrainedSize
594594
_layout = [self calculateLayoutThatFits:constrainedSize];
595595
_constrainedSize = constrainedSize;
596596
_flags.isMeasured = YES;
597+
[self calculatedLayoutDidChange];
597598
}
598599

599600
ASDisplayNodeAssertTrue(_layout.layoutableObject == self);
@@ -615,6 +616,10 @@ - (ASLayout *)__measureWithSizeRange:(ASSizeRange)constrainedSize
615616
return _layout;
616617
}
617618

619+
- (void)calculatedLayoutDidChange
620+
{
621+
}
622+
618623
- (BOOL)displaysAsynchronously
619624
{
620625
ASDN::MutexLocker l(_propertyLock);

AsyncDisplayKit/ASTextNode.mm

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -185,19 +185,6 @@ - (NSString *)description
185185

186186
#pragma mark - ASDisplayNode
187187

188-
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
189-
{
190-
ASDisplayNodeAssert(constrainedSize.width >= 0, @"Constrained width for text (%f) is too narrow", constrainedSize.width);
191-
ASDisplayNodeAssert(constrainedSize.height >= 0, @"Constrained height for text (%f) is too short", constrainedSize.height);
192-
193-
_constrainedSize = constrainedSize;
194-
[self _invalidateRenderer];
195-
ASDisplayNodeRespectThreadAffinityOfNode(self, ^{
196-
[self setNeedsDisplay];
197-
});
198-
return [[self _renderer] size];
199-
}
200-
201188
// FIXME: Re-evaluate if it is still the right decision to clear the renderer at this stage.
202189
// This code was written before TextKit and when 512MB devices were still the overwhelming majority.
203190
- (void)displayDidFinish
@@ -303,6 +290,8 @@ - (void)_invalidateRendererIfNeededForBoundsSize:(CGSize)boundsSize
303290
}
304291
}
305292

293+
#pragma mark - Layout and Sizing
294+
306295
- (BOOL)_needInvalidateRendererForBoundsSize:(CGSize)boundsSize
307296
{
308297
if (!_renderer) {
@@ -323,7 +312,7 @@ - (BOOL)_needInvalidateRendererForBoundsSize:(CGSize)boundsSize
323312
// as this would essentially serve to set its constrainedSize to be its calculatedSize (unnecessary).
324313
ASLayout *layout = self.calculatedLayout;
325314
if (layout != nil && CGSizeEqualToSize(boundsSize, layout.size)) {
326-
if (!CGSizeEqualToSize(boundsSize, rendererConstrainedSize)) {
315+
if (boundsSize.width != rendererConstrainedSize.width) {
327316
// Don't bother changing _constrainedSize, as ASDisplayNode's -measure: method would have a cache miss
328317
// and ask us to recalculate layout if it were called with the same calculatedSize that got us to this point!
329318
_renderer.constrainedSize = boundsSize;
@@ -335,6 +324,32 @@ - (BOOL)_needInvalidateRendererForBoundsSize:(CGSize)boundsSize
335324
}
336325
}
337326

327+
- (void)calculatedLayoutDidChange
328+
{
329+
ASLayout *layout = self.calculatedLayout;
330+
if (layout != nil) {
331+
_renderer.constrainedSize = layout.size;
332+
}
333+
}
334+
335+
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
336+
{
337+
ASDisplayNodeAssert(constrainedSize.width >= 0, @"Constrained width for text (%f) is too narrow", constrainedSize.width);
338+
ASDisplayNodeAssert(constrainedSize.height >= 0, @"Constrained height for text (%f) is too short", constrainedSize.height);
339+
340+
_constrainedSize = constrainedSize;
341+
342+
// Instead of invalidating the renderer, in case this is a new call with a different constrained size,
343+
// just update the size of the NSTextContainer that is owned by the renderer's internal context object.
344+
[self _renderer].constrainedSize = _constrainedSize;
345+
346+
ASDisplayNodeRespectThreadAffinityOfNode(self, ^{
347+
[self setNeedsDisplay];
348+
});
349+
350+
return [[self _renderer] size];
351+
}
352+
338353
#pragma mark - Modifying User Text
339354

340355
- (void)setAttributedString:(NSAttributedString *)attributedString

0 commit comments

Comments
 (0)