Possible fix for 18890 (#19687)
Summary: Potential fixes for 18890. The issue was that when the setAttributedText method in RCTBaseTextInputView.m is called it does two main things: Check that the attributed text that it receives is equal to the existing attributed text in the underlying backed up view ( backedTextInputView) If not set the attributed text of the backed up view to the value passed into the method. This kills the dictation as it is effectively the equivalent of typing in the backed up text view. self.backedTextInputView.attributedText = attributedText; is the problem. It kills the dictation. It may have other effects as well. In all cases I have seen the underlying text of the attributed string that is passed in the same as the text in the backedTextInputView, what was said to the dictation; however the attributes are different, which causes the isEqualToAttributedString: check to fail and thus the update happens, and the keyboard is killed. Fix is to test for the underlying string equality not the attributed string equality when the input mode is dictation. By necessity this had to be an integration test on an existing application. To test I enabled the keyboard and started the dictation. It worked with this fixes and not without. Will upload videos later. This might break attributes on dictation, as it is happening. However anything set on the existing underlying text view should hold. [IOS] [BUG] [Textinput] fixed an issue where the keyboard dictation ended abruptly. Closes https://github.com/facebook/react-native/pull/19687 Differential Revision: D8450590 Pulled By: hramos fbshipit-source-id: f97084131f98e9e0ed1f32111afc0f9f510f3b3b
This commit is contained in:
parent
4e1abdd74d
commit
a7a2ef1bb6
|
@ -98,10 +98,22 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
|
|||
return self.backedTextInputView.attributedText;
|
||||
}
|
||||
|
||||
- (BOOL)textOf:(NSAttributedString*)newText equals:(NSAttributedString*)oldText{
|
||||
UITextInputMode *currentInputMode = self.backedTextInputView.textInputMode;
|
||||
if ([currentInputMode.primaryLanguage isEqualToString:@"dictation"]) {
|
||||
// When the dictation is running we can't update the attibuted text on the backed up text view
|
||||
// because setting the attributed string will kill the dictation. This means that we can't impose
|
||||
// the settings on a dictation.
|
||||
return ([newText.string isEqualToString:oldText.string]);
|
||||
} else {
|
||||
return ([newText isEqualToAttributedString:oldText]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setAttributedText:(NSAttributedString *)attributedText
|
||||
{
|
||||
NSInteger eventLag = _nativeEventCount - _mostRecentEventCount;
|
||||
|
||||
BOOL textNeedsUpdate = NO;
|
||||
// Remove tag attribute to ensure correct attributed string comparison.
|
||||
NSMutableAttributedString *const backedTextInputViewTextCopy = [self.backedTextInputView.attributedText mutableCopy];
|
||||
NSMutableAttributedString *const attributedTextCopy = [attributedText mutableCopy];
|
||||
|
@ -111,8 +123,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
|
|||
|
||||
[attributedTextCopy removeAttribute:RCTTextAttributesTagAttributeName
|
||||
range:NSMakeRange(0, attributedTextCopy.length)];
|
||||
|
||||
if (eventLag == 0 && ![attributedTextCopy isEqualToAttributedString:backedTextInputViewTextCopy]) {
|
||||
|
||||
textNeedsUpdate = ([self textOf:attributedTextCopy equals:backedTextInputViewTextCopy] == NO);
|
||||
|
||||
if (eventLag == 0 && textNeedsUpdate) {
|
||||
UITextRange *selection = self.backedTextInputView.selectedTextRange;
|
||||
NSInteger oldTextLength = self.backedTextInputView.attributedText.string.length;
|
||||
|
||||
|
@ -121,13 +135,13 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
|
|||
if (selection.empty) {
|
||||
// Maintaining a cursor position relative to the end of the old text.
|
||||
NSInteger offsetStart =
|
||||
[self.backedTextInputView offsetFromPosition:self.backedTextInputView.beginningOfDocument
|
||||
toPosition:selection.start];
|
||||
[self.backedTextInputView offsetFromPosition:self.backedTextInputView.beginningOfDocument
|
||||
toPosition:selection.start];
|
||||
NSInteger offsetFromEnd = oldTextLength - offsetStart;
|
||||
NSInteger newOffset = attributedText.string.length - offsetFromEnd;
|
||||
UITextPosition *position =
|
||||
[self.backedTextInputView positionFromPosition:self.backedTextInputView.beginningOfDocument
|
||||
offset:newOffset];
|
||||
[self.backedTextInputView positionFromPosition:self.backedTextInputView.beginningOfDocument
|
||||
offset:newOffset];
|
||||
[self.backedTextInputView setSelectedTextRange:[self.backedTextInputView textRangeFromPosition:position toPosition:position]
|
||||
notifyDelegate:YES];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue