@@ -356,22 +356,15 @@ - (void)renderMarkdownContent:(NSString *)markdownString
356356 });
357357}
358358
359- - (void ) renderMarkdownSynchronously : (NSString *)markdownString
359+ - (NSArray *) parseAndRenderSegments : (NSString *)markdownString
360360{
361- if (!markdownString || markdownString.length == 0 ) {
362- return ;
363- }
364-
365- _blockAsyncRender = YES ;
366- _cachedMarkdown = [markdownString copy ];
367- _renderedMarkdown = [markdownString copy ];
368-
369361 MarkdownASTNode *ast = [_parser parseMarkdown: markdownString flags: _md4cFlags];
370362 if (!ast) {
371- return ;
363+ return nil ;
372364 }
373365
374366 NSArray *segments = [self splitASTIntoSegments: ast];
367+ NSMutableArray *renderedSegments = [NSMutableArray array ];
375368
376369 for (id segment in segments) {
377370 if ([segment isKindOfClass: [EMTextSegment class ]]) {
@@ -380,19 +373,54 @@ - (void)renderMarkdownSynchronously:(NSString *)markdownString
380373 allowTrailingMargin: _allowTrailingMargin
381374 allowFontScaling: _fontScaleObserver.allowFontScaling
382375 maxFontSizeMultiplier: _maxFontSizeMultiplier];
383- EnrichedMarkdownInternalText *view = [self createTextViewForRenderedSegment: rendered];
376+ [renderedSegments addObject: rendered];
377+ } else if ([segment isKindOfClass: [EMTableSegment class ]]) {
378+ [renderedSegments addObject: segment];
379+ }
380+ #if ENRICHED_MARKDOWN_MATH
381+ else if ([segment isKindOfClass: [EMMathSegment class ]]) {
382+ [renderedSegments addObject: segment];
383+ }
384+ #endif
385+ }
386+
387+ return renderedSegments;
388+ }
389+
390+ // / Synchronous rendering for mock view measurement (no UI updates needed).
391+ - (void )renderMarkdownSynchronously : (NSString *)markdownString
392+ {
393+ if (!markdownString || markdownString.length == 0 ) {
394+ return ;
395+ }
396+
397+ for (UIView *view in _segmentViews) {
398+ [view removeFromSuperview ];
399+ }
400+ [_segmentViews removeAllObjects ];
401+
402+ _blockAsyncRender = YES ;
403+ _cachedMarkdown = [markdownString copy ];
404+ _renderedMarkdown = [markdownString copy ];
405+
406+ NSArray *renderedSegments = [self parseAndRenderSegments: markdownString];
407+ if (!renderedSegments) {
408+ return ;
409+ }
410+
411+ for (id segment in renderedSegments) {
412+ if ([segment isKindOfClass: [EMRenderedTextSegment class ]]) {
413+ EnrichedMarkdownInternalText *view = [self createTextViewForRenderedSegment: (EMRenderedTextSegment *)segment];
384414 [_segmentViews addObject: view];
385415 [self addSubview: view];
386416 } else if ([segment isKindOfClass: [EMTableSegment class ]]) {
387- EMTableSegment *tableSegment = (EMTableSegment *)segment;
388- TableContainerView *tableView = [self createTableViewForSegment: tableSegment];
417+ TableContainerView *tableView = [self createTableViewForSegment: (EMTableSegment *)segment];
389418 [_segmentViews addObject: tableView];
390419 [self addSubview: tableView];
391420 }
392421#if ENRICHED_MARKDOWN_MATH
393422 else if ([segment isKindOfClass: [EMMathSegment class ]]) {
394- EMMathSegment *mathSegment = (EMMathSegment *)segment;
395- ENRMMathContainerView *mathView = [self createMathViewForSegment: mathSegment];
423+ ENRMMathContainerView *mathView = [self createMathViewForSegment: (EMMathSegment *)segment];
396424 [_segmentViews addObject: mathView];
397425 [self addSubview: mathView];
398426 }
@@ -430,11 +458,17 @@ - (void)applyRenderedSegments:(NSArray *)renderedSegments
430458#endif
431459 }
432460
433- if (needsHeightUpdate ([self measureSize: self .bounds.size.width], self.bounds )) {
434- [self requestHeightUpdate ];
435- }
461+ // When bounds width is zero (recycled view not yet laid out), skip
462+ // measurement — didMoveToWindow will handle it once the view has real
463+ // bounds. Measuring with width=0 produces a bogus single-line measurement
464+ // that corrupts the height sent to Yoga.
465+ if (self.bounds .size .width > 0 ) {
466+ [self setNeedsLayout ];
436467
437- [self setNeedsLayout ];
468+ if (needsHeightUpdate ([self measureSize: self .bounds.size.width], self.bounds )) {
469+ [self requestHeightUpdate ];
470+ }
471+ }
438472}
439473
440474- (EMRenderedTextSegment *)renderTextSegment : (EMTextSegment *)textSegment
@@ -615,18 +649,25 @@ - (void)didMoveToWindow
615649 EnrichedMarkdownInternalText *textSegment = (EnrichedMarkdownInternalText *)segment;
616650 UITextView *textView = textSegment.textView ;
617651 textView.contentOffset = CGPointZero;
652+
653+ textView.frame = textSegment.bounds ;
654+ textView.textContainer .size = CGSizeMake (textView.bounds .size .width , CGFLOAT_MAX);
655+
618656 if (textView.attributedText .length > 0 ) {
619657 [textView.layoutManager invalidateLayoutForCharacterRange: NSMakeRange (0 , textView.attributedText.length)
620658 actualCharacterRange: NULL ];
621- textView.textContainer .size = CGSizeMake (textView.bounds .size .width , CGFLOAT_MAX);
622- [textView setNeedsLayout ];
623- [textView layoutIfNeeded ];
624- [textView setNeedsDisplay ];
659+ [textView.layoutManager ensureLayoutForTextContainer: textView.textContainer];
625660 }
661+
662+ [textView layoutIfNeeded ];
663+ [textView setNeedsDisplay ];
626664 }
627665 }
628666
629- [self requestHeightUpdate ];
667+ CGSize measured = [self measureSize: self .bounds.size.width];
668+ if (needsHeightUpdate (measured, self.bounds )) {
669+ [self requestHeightUpdate ];
670+ }
630671 }
631672}
632673
0 commit comments