diff --git a/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt b/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt index 2c820f455..d01aa7289 100644 --- a/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +++ b/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt @@ -70,6 +70,8 @@ class EnrichedTextInputView : AppCompatEditText { private var fontFamily: String? = null private var fontStyle: Int = ReactConstants.UNSET private var fontWeight: Int = ReactConstants.UNSET + private var defaultValue: CharSequence? = null + private var defaultValueDirty: Boolean = false private var inputMethodManager: InputMethodManager? = null @@ -360,7 +362,24 @@ class EnrichedTextInputView : AppCompatEditText { return false } - fun updateTypeface() { + fun afterUpdateTransaction() { + updateTypeface() + updateDefaultValue() + } + + fun setDefaultValue(value: CharSequence?) { + defaultValue = value + defaultValueDirty = true + } + + private fun updateDefaultValue() { + if (!defaultValueDirty) return + + defaultValueDirty = false + setValue(defaultValue ?: "") + } + + private fun updateTypeface() { if (!typefaceDirty) return typefaceDirty = false diff --git a/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt b/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt index 1e6957518..aba765359 100644 --- a/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +++ b/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt @@ -77,7 +77,7 @@ class EnrichedTextInputViewManager : SimpleViewManager(), @ReactProp(name = "defaultValue") override fun setDefaultValue(view: EnrichedTextInputView?, value: String?) { - view?.setValue(value) + view?.setDefaultValue(value) } @ReactProp(name = "placeholder") @@ -156,7 +156,7 @@ class EnrichedTextInputViewManager : SimpleViewManager(), override fun onAfterUpdateTransaction(view: EnrichedTextInputView) { super.onAfterUpdateTransaction(view) - view.updateTypeface() + view.afterUpdateTransaction() } override fun setPadding( diff --git a/ios/EnrichedTextInputView.mm b/ios/EnrichedTextInputView.mm index a2d4cd326..df6783fed 100644 --- a/ios/EnrichedTextInputView.mm +++ b/ios/EnrichedTextInputView.mm @@ -601,6 +601,9 @@ - (void)tryUpdatingActiveStyles { // style updates are emitted only if something differs from the previously active styles BOOL updateNeeded = NO; + // active styles are kept in a separate set until we're sure they can be emitted + NSMutableSet *newActiveStyles = [_activeStyles mutableCopy]; + // data for onLinkDetected event LinkData *detectedLinkData; NSRange detectedLinkRange = NSMakeRange(0, 0); @@ -611,14 +614,14 @@ - (void)tryUpdatingActiveStyles { for (NSNumber* type in stylesDict) { id style = stylesDict[type]; - BOOL wasActive = [_activeStyles containsObject: type]; + BOOL wasActive = [newActiveStyles containsObject: type]; BOOL isActive = [style detectStyle:textView.selectedRange]; if(wasActive != isActive) { updateNeeded = YES; if(isActive) { - [_activeStyles addObject:type]; + [newActiveStyles addObject:type]; } else { - [_activeStyles removeObject:type]; + [newActiveStyles removeObject:type]; } } @@ -678,6 +681,9 @@ - (void)tryUpdatingActiveStyles { if(updateNeeded) { auto emitter = [self getEventEmitter]; if(emitter != nullptr) { + // update activeStyles only if emitter is available + _activeStyles = newActiveStyles; + emitter->onChangeState({ .isBold = [_activeStyles containsObject: @([BoldStyle getStyleType])], .isItalic = [_activeStyles containsObject: @([ItalicStyle getStyleType])], @@ -990,6 +996,9 @@ - (void)manageSelectionBasedChanges { textView.typingAttributes = defaultTypingAttributes; } } + + // update active styles as well + [self tryUpdatingActiveStyles]; } - (void)handleWordModificationBasedChanges:(NSString*)word inRange:(NSRange)range { @@ -1105,17 +1114,18 @@ - (void)_performRelayout if (!textView) { return; } dispatch_async(dispatch_get_main_queue(), ^{ - NSRange wholeRange = NSMakeRange(0, textView.textStorage.string.length); + NSRange wholeRange = NSMakeRange(0, self->textView.textStorage.string.length); NSRange actualRange = NSMakeRange(0, 0); - [textView.layoutManager invalidateLayoutForCharacterRange:wholeRange actualCharacterRange:&actualRange]; - [textView.layoutManager ensureLayoutForCharacterRange:actualRange]; - [textView.layoutManager invalidateDisplayForCharacterRange:wholeRange]; + [self->textView.layoutManager invalidateLayoutForCharacterRange:wholeRange actualCharacterRange:&actualRange]; + [self->textView.layoutManager ensureLayoutForCharacterRange:actualRange]; + [self->textView.layoutManager invalidateDisplayForCharacterRange:wholeRange]; }); } - (void)didMoveToWindow { [super didMoveToWindow]; - [self scheduleRelayoutIfNeeded]; + // used to run all lifecycle callbacks + [self anyTextMayHaveBeenModified]; } // MARK: - UITextView delegate methods @@ -1200,9 +1210,6 @@ - (void)textViewDidChangeSelection:(UITextView *)textView { // manage selection changes [self manageSelectionBasedChanges]; - - // update active styles - [self tryUpdatingActiveStyles]; } // this function isn't called always when some text changes (for example setting link or starting mention with indicator doesn't fire it)