diff --git a/packages/react-native/React/CoreModules/RCTActionSheetManager.mm b/packages/react-native/React/CoreModules/RCTActionSheetManager.mm index d615eca6e8a..f95b684ec56 100644 --- a/packages/react-native/React/CoreModules/RCTActionSheetManager.mm +++ b/packages/react-native/React/CoreModules/RCTActionSheetManager.mm @@ -22,6 +22,55 @@ using namespace facebook::react; +@interface RCTShareActivityItemSource : NSObject + +- (instancetype)initWithItem:(id)item pasteboardItem:(nullable id)pasteboardItem subject:(nullable NSString *)subject; + +@end + +@implementation RCTShareActivityItemSource { + id _item; + id _pasteboardItem; + NSString *_subject; +} + +- (instancetype)initWithItem:(id)item pasteboardItem:(nullable id)pasteboardItem subject:(nullable NSString *)subject +{ + if (self = [super init]) { + _item = item; + _pasteboardItem = pasteboardItem; + _subject = subject; + } + return self; +} + +- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController +{ + return _item; +} + +- (nullable id)activityViewController:(UIActivityViewController *)activityViewController + itemForActivityType:(nullable UIActivityType)activityType +{ + return [activityType isEqualToString:UIActivityTypeCopyToPasteboard] ? _pasteboardItem : _item; +} + +- (BOOL)respondsToSelector:(SEL)selector +{ + if (selector == @selector(activityViewController:subjectForActivityType:)) { + return _subject != nil; + } + return [super respondsToSelector:selector]; +} + +- (NSString *)activityViewController:(UIActivityViewController *)activityViewController + subjectForActivityType:(nullable UIActivityType)activityType +{ + return _subject; +} + +@end + @interface RCTActionSheetManager () @property (nonatomic, strong) NSMutableArray *alertControllers; @@ -264,6 +313,14 @@ - (void)showShareActionSheetWithOptions: return; } [items addObject:data]; + } else if (message != nullptr && !URL.fileURL) { + // On Copy, UIKit writes each activity item to its own pasteboard item, and a plain-text + // paste (including through Universal Clipboard) only reads the first one. + NSString *pasteboardText = [NSString stringWithFormat:@"%@ %@", message, URL.absoluteString]; + items[0] = [[RCTShareActivityItemSource alloc] initWithItem:message + pasteboardItem:pasteboardText + subject:subject]; + [items addObject:[[RCTShareActivityItemSource alloc] initWithItem:URL pasteboardItem:nil subject:subject]]; } else { [items addObject:URL]; }