First of all, you need to create a class that conforms to UIActivityItemSource
, and use it instead of passing the text or image directly to UIActivityViewController
.
So instead of
UIActivityViewController(activityItems: [image, text])
We would pass the new item sources
UIActivityViewController(activityItems: [ImageItemSource(image), TextItemSource(text)]
The item source classes will look something like this:
class TextItemSource: NSObject, UIActivityItemSource {
private let text: String
init(text: String) {
self.text = text
super.init()
}
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
text
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
text
}
}
class ImageItemSource: NSObject, UIActivityItemSource {
private let image: UIImage
init(image: UIImage) {
self.image = image
super.init()
}
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
image
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
image
}
}
Now that we have control over what we'll share, we can choose what exactly we share with each app by checking activityType
before returning the data, and if we think we should not send anything at all, we can simply return nil
.
In your case, if you want to share the text item with all apps except WhatsApp, you can simply do this:
class TextItemSource: NSObject, UIActivityItemSource {
...
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
if activityType?.rawValue.starts(with: "net.whatsapp.WhatsApp.") == true {
// We'll return `nil` to WhatsApp forcing it to
// ignore this whole text item and only show the image item instead
return nil
}
return text
}
...
}