Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt iOS16+ dictation #37188

Closed
21 changes: 20 additions & 1 deletion Libraries/Text/TextInput/RCTBaseTextInputShadowView.m
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,26 @@ - (void)uiManagerWillPerformMounting
// Don't set `attributedText` if length equal to zero, otherwise it would shrink when attributes contain like
// `lineHeight`.
if (newAttributedText.length != 0) {
baseTextInputView.attributedText = newAttributedText;
// When we start using the dictation on the keyboard, the system will automatically
// generate a `_UITextPlaceholderAttachment`, when the speech recognition ends,
// the system will delete `_UITextPlaceholderAttachment` and replace it with the recognized text,
// but when we pass `_UITextPlaceholderAttachment` to Javascript,
// we will force convert `_UITextPlaceholderAttachment` object to `\uFFFC`,
// so after the system speech recognition is completed, the `_UITextPlaceholderAttachment` cannot be found.

// So: We reverse `\uFFFC` to private class `_UITextPlaceholderAttachment` object

NSMutableAttributedString *newMutableAttributedString = [newAttributedText mutableCopy];
[baseTextInputView.attributedText enumerateAttribute:NSAttachmentAttributeName inRange:NSMakeRange(0, baseTextInputView.attributedText.length) options:kNilOptions usingBlock:^(id _Nullable attachment, NSRange range, BOOL * _Nonnull stop) {
if (![[[baseTextInputView.attributedText attributedSubstringFromRange:range] string] isEqualToString:[[newMutableAttributedString attributedSubstringFromRange:range] string]]) {
return;
}
if (!attachment || ![NSStringFromClass([attachment class]) isEqualToString:@"_UITextPlaceholderAttachment"]) {
return;
}
[newMutableAttributedString addAttribute:NSAttachmentAttributeName value:attachment range:range];
}];
baseTextInputView.attributedText = newMutableAttributedString;
} else {
baseTextInputView.attributedText = nil;
}
Expand Down