react-native-highlight-text-view 0.1.18 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -315,40 +315,60 @@ class HighlightTextView : AppCompatEditText {
315
315
  Typeface.create(baseTypeface, style)
316
316
  }
317
317
 
318
- // Save current text to force complete rebuild
318
+ // Save current text and selection
319
319
  val currentText = text?.toString() ?: ""
320
320
  val currentSelection = selectionStart
321
321
 
322
+ // Apply new typeface
322
323
  this.typeface = typeface
323
324
 
324
- // Force complete text rebuild with new font metrics
325
- // This is crucial for fonts with different ascender/descender values like Eczar
325
+ // CRITICAL: Force complete layout rebuild for fonts with different metrics (like Eczar)
326
+ // Multiple post calls ensure all layout phases complete with new font
326
327
  post {
327
- // Clear text first to force layout recalculation
328
328
  isUpdatingText = true
329
+
330
+ // Phase 1: Clear everything
329
331
  setText("")
332
+ paint.typeface = typeface // Ensure paint also has new typeface
330
333
 
331
- // Force measure and layout with empty text
334
+ // Force measure with empty text and new font
332
335
  measure(
333
336
  MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
334
337
  MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
335
338
  )
339
+ layout(left, top, right, bottom)
336
340
 
337
- // Restore text - this triggers complete rebuild with new font metrics
338
- setText(currentText)
339
-
340
- // Reapply all character backgrounds with new font metrics
341
- applyCharacterBackgrounds()
342
-
343
- // Restore cursor position
344
- val safePosition = currentSelection.coerceIn(0, currentText.length)
345
- setSelection(safePosition)
346
-
347
- isUpdatingText = false
348
-
349
- // Force complete layout recalculation
350
- requestLayout()
351
- invalidate()
341
+ // Phase 2: Restore text and rebuild (next frame)
342
+ post {
343
+ setText(currentText)
344
+
345
+ // Force another measure/layout cycle with actual text
346
+ measure(
347
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
348
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
349
+ )
350
+ layout(left, top, right, bottom)
351
+
352
+ // Phase 3: Apply backgrounds and finalize (next frame)
353
+ post {
354
+ applyCharacterBackgrounds()
355
+
356
+ // Restore cursor position
357
+ val safePosition = currentSelection.coerceIn(0, currentText.length)
358
+ setSelection(safePosition)
359
+
360
+ isUpdatingText = false
361
+
362
+ // Final layout pass
363
+ requestLayout()
364
+ invalidate()
365
+
366
+ // Extra invalidate to ensure rendering
367
+ post {
368
+ invalidate()
369
+ }
370
+ }
371
+ }
352
372
  }
353
373
  }
354
374
 
@@ -528,33 +528,51 @@ Class<RCTComponentViewProtocol> HighlightTextViewCls(void)
528
528
  newFont = [UIFont systemFontOfSize:fontSize weight:fontWeight];
529
529
  }
530
530
 
531
- _textView.font = newFont;
532
-
533
- // Save current text to force complete rebuild
531
+ // Save current text and selection
534
532
  NSString *currentText = [_textView.text copy];
533
+ NSRange currentSelection = _textView.selectedRange;
535
534
 
536
- // Clear text storage to force complete recalculation
537
- [_textView.textStorage beginEditing];
538
- [_textView.textStorage replaceCharactersInRange:NSMakeRange(0, _textView.textStorage.length) withString:@""];
539
- [_textView.textStorage endEditing];
535
+ // Update font on text view
536
+ _textView.font = newFont;
540
537
 
541
- // Force layout manager to invalidate everything
542
- [_layoutManager invalidateLayoutForCharacterRange:NSMakeRange(0, 0) actualCharacterRange:NULL];
543
- [_layoutManager invalidateDisplayForCharacterRange:NSMakeRange(0, 0)];
538
+ // CRITICAL: Force complete rebuild by removing and re-adding the text container
539
+ // This ensures all glyph and layout caches are cleared for the new font metrics
540
+ NSTextContainer *textContainer = _textView.textContainer;
541
+ NSTextStorage *textStorage = _textView.textStorage;
544
542
 
545
- // Restore text and rebuild with new font
546
- _textView.text = currentText;
543
+ // Remove text container from layout manager
544
+ [_layoutManager removeTextContainerAtIndex:0];
547
545
 
548
- // Reapply character backgrounds with new font metrics - this rebuilds attributed text
549
- [self applyCharacterBackgrounds];
546
+ // Completely invalidate all layout
547
+ [_layoutManager invalidateLayoutForCharacterRange:NSMakeRange(0, textStorage.length) actualCharacterRange:NULL];
548
+ [_layoutManager invalidateDisplayForCharacterRange:NSMakeRange(0, textStorage.length)];
550
549
 
551
- // Force complete layout recalculation
552
- [_textView.layoutManager ensureLayoutForTextContainer:_textView.textContainer];
550
+ // Re-add text container - forces complete layout recalculation
551
+ [_layoutManager addTextContainer:textContainer];
553
552
 
554
- // Force the text view to redraw
555
- [_textView setNeedsDisplay];
556
- [_textView setNeedsLayout];
557
- [_textView layoutIfNeeded];
553
+ // Force immediate layout with new font metrics
554
+ dispatch_async(dispatch_get_main_queue(), ^{
555
+ // Restore text through applyCharacterBackgrounds which rebuilds attributed string
556
+ [self applyCharacterBackgrounds];
557
+
558
+ // Ensure layout is calculated with new font
559
+ [self->_layoutManager ensureLayoutForTextContainer:self->_textView.textContainer];
560
+
561
+ // Restore selection if valid
562
+ if (currentSelection.location <= currentText.length) {
563
+ self->_textView.selectedRange = currentSelection;
564
+ }
565
+
566
+ // Force complete redraw
567
+ [self->_textView setNeedsDisplay];
568
+ [self->_textView setNeedsLayout];
569
+ [self->_textView layoutIfNeeded];
570
+
571
+ // Trigger another display update to ensure rendering
572
+ dispatch_async(dispatch_get_main_queue(), ^{
573
+ [self->_textView setNeedsDisplay];
574
+ });
575
+ });
558
576
  }
559
577
 
560
578
  - (void)applyCharacterBackgrounds
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-highlight-text-view",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "A native text input for React Native that supports inline text highlighting",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",