diff --git a/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm b/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm index 95ff5a0d180e..b988908b6fd6 100644 --- a/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm +++ b/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm @@ -405,6 +405,9 @@ void RCTApplyBaselineOffset(NSMutableAttributedString *attributedText) const AttributedString::Fragment &fragment, UIImage *placeholderImage) { + NSString *string; + NSMutableDictionary *attributes; + if (fragment.isAttachment()) { auto layoutMetrics = fragment.parentShadowView.layoutMetrics; CGRect bounds = { @@ -415,41 +418,28 @@ void RCTApplyBaselineOffset(NSMutableAttributedString *attributedText) attachment.image = placeholderImage; attachment.bounds = bounds; - return [[NSMutableAttributedString attributedStringWithAttachment:attachment] mutableCopy]; + string = [NSString stringWithFormat:@"%C", (unichar)NSAttachmentCharacter]; + attributes = [NSMutableDictionary dictionaryWithObject:attachment forKey:NSAttachmentAttributeName]; } else { NSString *decoded = [[NSString alloc] initWithBytes:fragment.string.data() length:fragment.string.size() encoding:NSUTF8StringEncoding]; - NSString *string = decoded != nil ? decoded : @""; + string = decoded != nil ? decoded : @""; if (fragment.textAttributes.textTransform.has_value()) { auto textTransform = fragment.textAttributes.textTransform.value(); string = RCTNSStringFromStringApplyingTextTransform(string, textTransform); } - return [[NSMutableAttributedString alloc] - initWithString:string - attributes:RCTNSTextAttributesFromTextAttributes(fragment.textAttributes)]; + attributes = RCTNSTextAttributesFromTextAttributes(fragment.textAttributes); } -} - -static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFromFragment( - const AttributedString::Fragment &fragment, - UIImage *placeholderImage) -{ - auto nsAttributedStringFragment = RCTNSAttributedStringFragmentFromFragment(fragment, placeholderImage); + // Set with the initial attributes; adding it afterwards would re-split the runs. if (fragment.parentShadowView.componentHandle) { - auto eventEmitterWrapper = RCTWrapEventEmitter(fragment.parentShadowView.eventEmitter); - - NSDictionary *additionalTextAttributes = - @{RCTAttributedStringEventEmitterKey : eventEmitterWrapper}; - - [nsAttributedStringFragment addAttributes:additionalTextAttributes - range:NSMakeRange(0, nsAttributedStringFragment.length)]; + attributes[RCTAttributedStringEventEmitterKey] = RCTWrapEventEmitter(fragment.parentShadowView.eventEmitter); } - return nsAttributedStringFragment; + return [[NSMutableAttributedString alloc] initWithString:string attributes:attributes]; } NSAttributedString *RCTNSAttributedStringFromAttributedString(const AttributedString &attributedString) @@ -464,9 +454,9 @@ void RCTApplyBaselineOffset(NSMutableAttributedString *attributedText) [nsAttributedString beginEditing]; - for (auto fragment : attributedString.getFragments()) { + for (const auto &fragment : attributedString.getFragments()) { NSMutableAttributedString *nsAttributedStringFragment = - RCTNSAttributedStringFragmentWithAttributesFromFragment(fragment, placeholderImage); + RCTNSAttributedStringFragmentFromFragment(fragment, placeholderImage); [nsAttributedString appendAttributedString:nsAttributedStringFragment]; }