Skip to content

Commit a662c35

Browse files
szydlovskyexploIF
andauthored
fix: state change emitting with default values improvement (#251)
Fixes: #237 Turns out `eventEmitter` isn't available from the very beginning, but the iOS code was remembering recently active styles even if no state change event was emitted. This way, when the event emitter was finally available, no state change event was emitted because recently active styles were exactly same (even though no event went out). Except that, I added all lifecycle callbacks (`anyTextMayHaveBeenModified` that e.g. runs the state change event) to the `didMoveToWindow` because it seems like the event emitter is defined then. The issue was;`defaultValue` was set but its state changes emitted only when some change was done to an input (and not on focus or when eventEmitter is available). The PR fixes both scenarios. --------- Co-authored-by: Igor Furgała <74370735+exploIF@users.noreply.github.com>
1 parent f4ed003 commit a662c35

1 file changed

Lines changed: 18 additions & 11 deletions

File tree

ios/EnrichedTextInputView.mm

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,9 @@ - (void)tryUpdatingActiveStyles {
601601
// style updates are emitted only if something differs from the previously active styles
602602
BOOL updateNeeded = NO;
603603

604+
// active styles are kept in a separate set until we're sure they can be emitted
605+
NSMutableSet *newActiveStyles = [_activeStyles mutableCopy];
606+
604607
// data for onLinkDetected event
605608
LinkData *detectedLinkData;
606609
NSRange detectedLinkRange = NSMakeRange(0, 0);
@@ -611,14 +614,14 @@ - (void)tryUpdatingActiveStyles {
611614

612615
for (NSNumber* type in stylesDict) {
613616
id<BaseStyleProtocol> style = stylesDict[type];
614-
BOOL wasActive = [_activeStyles containsObject: type];
617+
BOOL wasActive = [newActiveStyles containsObject: type];
615618
BOOL isActive = [style detectStyle:textView.selectedRange];
616619
if(wasActive != isActive) {
617620
updateNeeded = YES;
618621
if(isActive) {
619-
[_activeStyles addObject:type];
622+
[newActiveStyles addObject:type];
620623
} else {
621-
[_activeStyles removeObject:type];
624+
[newActiveStyles removeObject:type];
622625
}
623626
}
624627

@@ -678,6 +681,9 @@ - (void)tryUpdatingActiveStyles {
678681
if(updateNeeded) {
679682
auto emitter = [self getEventEmitter];
680683
if(emitter != nullptr) {
684+
// update activeStyles only if emitter is available
685+
_activeStyles = newActiveStyles;
686+
681687
emitter->onChangeState({
682688
.isBold = [_activeStyles containsObject: @([BoldStyle getStyleType])],
683689
.isItalic = [_activeStyles containsObject: @([ItalicStyle getStyleType])],
@@ -990,6 +996,9 @@ - (void)manageSelectionBasedChanges {
990996
textView.typingAttributes = defaultTypingAttributes;
991997
}
992998
}
999+
1000+
// update active styles as well
1001+
[self tryUpdatingActiveStyles];
9931002
}
9941003

9951004
- (void)handleWordModificationBasedChanges:(NSString*)word inRange:(NSRange)range {
@@ -1105,17 +1114,18 @@ - (void)_performRelayout
11051114
if (!textView) { return; }
11061115

11071116
dispatch_async(dispatch_get_main_queue(), ^{
1108-
NSRange wholeRange = NSMakeRange(0, textView.textStorage.string.length);
1117+
NSRange wholeRange = NSMakeRange(0, self->textView.textStorage.string.length);
11091118
NSRange actualRange = NSMakeRange(0, 0);
1110-
[textView.layoutManager invalidateLayoutForCharacterRange:wholeRange actualCharacterRange:&actualRange];
1111-
[textView.layoutManager ensureLayoutForCharacterRange:actualRange];
1112-
[textView.layoutManager invalidateDisplayForCharacterRange:wholeRange];
1119+
[self->textView.layoutManager invalidateLayoutForCharacterRange:wholeRange actualCharacterRange:&actualRange];
1120+
[self->textView.layoutManager ensureLayoutForCharacterRange:actualRange];
1121+
[self->textView.layoutManager invalidateDisplayForCharacterRange:wholeRange];
11131122
});
11141123
}
11151124

11161125
- (void)didMoveToWindow {
11171126
[super didMoveToWindow];
1118-
[self scheduleRelayoutIfNeeded];
1127+
// used to run all lifecycle callbacks
1128+
[self anyTextMayHaveBeenModified];
11191129
}
11201130

11211131
// MARK: - UITextView delegate methods
@@ -1200,9 +1210,6 @@ - (void)textViewDidChangeSelection:(UITextView *)textView {
12001210

12011211
// manage selection changes
12021212
[self manageSelectionBasedChanges];
1203-
1204-
// update active styles
1205-
[self tryUpdatingActiveStyles];
12061213
}
12071214

12081215
// this function isn't called always when some text changes (for example setting link or starting mention with indicator doesn't fire it)

0 commit comments

Comments
 (0)