Set Different Activity Items for Uiactivityviewcontroller Swift

Set different activity items for UIActivityViewController Swift

You should take advantage of the UIActivityItemSource protocol. The activityItems parameter of the initializer of UIActivityViewController accepts either an array of data objects or an array of objects that implement the UIActivityItemSource protocol.

As an example consider an item source like the following.

class MyStringItemSource: NSObject, UIActivityItemSource {
@objc func activityViewControllerPlaceholderItem(activityViewController: UIActivityViewController) -> AnyObject {
return ""
}

@objc func activityViewController(activityViewController: UIActivityViewController, itemForActivityType activityType: String) -> AnyObject? {
if activityType == UIActivityTypeMessage {
return "String for message"
} else if activityType == UIActivityTypeMail {
return "String for mail"
} else if activityType == UIActivityTypePostToTwitter {
return "String for twitter"
} else if activityType == UIActivityTypePostToFacebook {
return "String for facebook"
}
return nil
}

func activityViewController(activityViewController: UIActivityViewController, subjectForActivityType activityType: String?) -> String {
if activityType == UIActivityTypeMessage {
return "Subject for message"
} else if activityType == UIActivityTypeMail {
return "Subject for mail"
} else if activityType == UIActivityTypePostToTwitter {
return "Subject for twitter"
} else if activityType == UIActivityTypePostToFacebook {
return "Subject for facebook"
}
return ""
}

func activityViewController(activityViewController: UIActivityViewController, thumbnailImageForActivityType activityType: String!, suggestedSize size: CGSize) -> UIImage! {
if activityType == UIActivityTypeMessage {
return UIImage(named: "thumbnail-for-message")
} else if activityType == UIActivityTypeMail {
return UIImage(named: "thumbnail-for-mail")
} else if activityType == UIActivityTypePostToTwitter {
return UIImage(named: "thumbnail-for-twitter")
} else if activityType == UIActivityTypePostToFacebook {
return UIImage(named: "thumbnail-for-facebook")
}
return UIImage(named: "some-default-thumbnail")
}
}

The above item source returns different string data objects, subjects and thumbnail images based on the activity type. To use, you just need to pass it into the UIActivityViewController initializer.

UIActivityViewController(activityItems: [MyStringItemSource()], applicationActivities: nil)

Similarly, you could define a custom MyUrlItemSource class that returns different URLs based on the selected activity and pass it along in the initializer.

UIActivityViewController(activityItems: [MyStringItemSource(), MyUrlItemSource()], applicationActivities: nil)

All of this is outlined in the official documentation for UIActivityViewController and UIActivityItemSource

Providing different shared items for each activity with UIActivityViewController

You can provide different data for different activities by creating a class that adopts UIActivityItemSource protocol and implements the method:

-(id)activityViewController:itemForActivityType:

Then pass the object of your custom class to your UIActivityViewController in activityItems array with a call -(id)initWithActivityItems:applicationActivities:

From documentation of this method:

... Instead of actual data objects, the objects in this array can be objects that adopt the UIActivityItemSource protocol, such as UIActivityItemProvider objects. ...

Here is a tutorial about how to do that: https://www.albertopasca.it/whiletrue/objective-c-custom-uiactivityviewcontroller-icons-and-text/

Sharing different content based on selected activity - UIActivityController

Just make a subclass of UIActivityItemProvider and override item property to give your custom activity items, i.e.

class CustomActivityItemProvider: UIActivityItemProvider
{
override var item: Any{
switch self.activityType!
{
case UIActivityType.postToFacebook:
return "Hello"
default:
return "Whatever"
}
}
}

Using it:

let activityItem = CustomActivityItemProvider(placeholderItem: "")
let activityViewController = UIActivityViewController(activityItems: [activityItem], applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)

Also, you can customize only those UIActivityType, that are exposed by Apple for use by developers. For UIActivityTypes refer to: https://developer.apple.com/documentation/uikit/uiactivitytype

UIActivityViewController to add additional types to UIPasteboard for 'copyToPasteboard' action

I've found a solution and my 'paste' process now recognises that there is both 'jsonData' and 'jsonString' on the pasteboard now, as well as attributed string and plain text.

Instead of adding 'self' to the 'items', I had to have 'self' as the ONLY item. Then I can define what items are returned by the protocol function:

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
guard let recipe = recipe else { return nil }
let attrString = someThing.attrString()
switch activityType {
case UIActivity.ActivityType.print:
return SomePrintPageRenderer(someThing)
case UIActivity.ActivityType.copyToPasteboard:
var pasteboardDict: [String:Any] = attrString.pasteables()
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
let jsonData = try? jsonEncoder.encode(someThing)
let jsonString = String(data: jsonData!, encoding: .utf8)
print(jsonString!)
if jsonData != nil {
pasteboardDict["jsonData"] = jsonData
if jsonString != nil {
pasteboardDict["jsonString"] = jsonString
}
}
return pasteboardDict
default:
return attrString
}
}

Note that I had to also explicitly handle the inclusion of the various plain and attributed string pasteboard types which I still require. (This has been done with a custom NSAttributedString extension with the function 'pasteables()' which returns a Dictionary of pasteable versions of the attributed string.)

IOS/Objective-C: UIActivityViewController: Customize for different Activity Types

You need to pass an instance or instances of your class that implements UIActivityItemSource when creating a UIActivityViewController with initWithActivityItems:applicationActivities: - see the documentation here. A view controller is probably not a good choice for this, I'd instead make dedicated objects to do this. Ultimately your code could look something like:

MySourceClass *mySource = [MySourceClass new];
NSArray *activityItems = @[mySource];
UIActivityViewController *activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:activityItems
applicationActivities:nil];


Related Topics



Leave a reply



Submit