How can I create a custom UIActivity in iOS?
First, create the files. I chose to name mine ActivityViewCustomActivity
Make ActivityViewCustomActivity.h look like this:
#import <UIKit/UIKit.h>@interface ActivityViewCustomActivity : UIActivity@end
Make ActivityViewCustomActivity.m look like this:
#import "ActivityViewCustomActivity.h"@implementation ActivityViewCustomActivity- (NSString *)activityType{ return @"yourappname.Review.App";}- (NSString *)activityTitle{ return @"Review App";}- (UIImage *)activityImage{ // Note: These images need to have a transparent background and I recommend these sizes: // iPadShare@2x should be 126 px, iPadShare should be 53 px, iPhoneShare@2x should be 100 // px, and iPhoneShare should be 50 px. I found these sizes to work for what I was making. if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { return [UIImage imageNamed:@"iPadShare.png"]; } else { return [UIImage imageNamed:@"iPhoneShare.png"]; }}- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems{ NSLog(@"%s", __FUNCTION__); return YES;}- (void)prepareWithActivityItems:(NSArray *)activityItems{ NSLog(@"%s",__FUNCTION__);}- (UIViewController *)activityViewController{ NSLog(@"%s",__FUNCTION__); return nil;}- (void)performActivity{ // This is where you can do anything you want, and is the whole reason for creating a custom // UIActivity [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=yourappid"]]; [self activityDidFinish:YES];}@end
This is what my image looked like:Here is the .PSD I made: -- malicious link removed --And here is the original 250 px .png http://i.imgur.com/pGWVj.png
Now in your view controller do this:
#import "ActivityViewCustomActivity.h"
And now wherever you want to display your UIActivityViewController
:
NSString *textItem = @"Check out the yourAppNameHere app: itunes http link to your app here"; UIImage *imageToShare = [UIImage imageNamed:@"anyImage.png"]; NSArray *items = [NSArray arrayWithObjects:textItem,imageToShare,nil]; ActivityViewCustomActivity *aVCA = [[ActivityViewCustomActivity alloc]init]; UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:[NSArray arrayWithObject:aVCA]]; activityVC.excludedActivityTypes = @[UIActivityTypePostToWeibo, UIActivityTypeAssignToContact, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeSaveToCameraRoll]; activityVC.completionHandler = ^(NSString *activityType, BOOL completed) { NSLog(@"ActivityType: %@", activityType); NSLog(@"Completed: %i", completed); }; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { self.popoverController = [[UIPopoverController alloc] initWithContentViewController:activityVC]; CGRect rect = [[UIScreen mainScreen] bounds]; [self.popoverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:0 animated:YES]; } else { [self presentViewController:activityVC animated:YES completion:nil]; }
Here is my Swift Version - I needed multiple custom actions so I created this class. No need for delegates or protocols.
1. Add the custom Class
class ActivityViewCustomActivity: UIActivity { var customActivityType = "" var activityName = "" var activityImageName = "" var customActionWhenTapped:( (Void)-> Void)! init(title: String, imageName:String, performAction: (() -> ()) ) { self.activityName = title self.activityImageName = imageName self.customActivityType = "Action \(title)" self.customActionWhenTapped = performAction super.init() } override func activityType() -> String? { return customActivityType } override func activityTitle() -> String? { return activityName } override func activityImage() -> UIImage? { return UIImage(named: activityImageName) } override func canPerformWithActivityItems(activityItems: [AnyObject]) -> Bool { return true } override func prepareWithActivityItems(activityItems: [AnyObject]) { // nothing to prepare } override func activityViewController() -> UIViewController? { return nil } override func performActivity() { customActionWhenTapped() }}
2 Use in your View Controller
I've attached it to a UIBarButtonItem, which calls the the following
@IBAction func actionButtonPressed(sender: UIBarButtonItem) { var sharingItems = [AnyObject]() // nothing to share... let myCustomActivity = ActivityViewCustomActivity(title: "Mark Selected", imageName: "removePin") { println("Do something") } let anotherCustomActivity = ActivityViewCustomActivity(title: "Reset All", imageName: "reload") { println("Do something else") } let activityViewController = UIActivityViewController(activityItems:sharingItems, applicationActivities:[myCustomActivity, anotherCustomActivity]) activityViewController.excludedActivityTypes = [UIActivityTypeMail, UIActivityTypeAirDrop, UIActivityTypeMessage, UIActivityTypeAssignToContact, UIActivityTypePostToFacebook, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeSaveToCameraRoll] activityViewController.popoverPresentationController?.barButtonItem = sender self.presentViewController(activityViewController, animated: true, completion: nil)}
My Swift 3 Implementation based off of DogCoffee's:
class ActivityViewCustomActivity: UIActivity { // MARK: Properties var customActivityType: UIActivityType var activityName: String var activityImageName: String var customActionWhenTapped: () -> Void // MARK: Initializer init(title: String, imageName: String, performAction: @escaping () -> Void) { self.activityName = title self.activityImageName = imageName self.customActivityType = UIActivityType(rawValue: "Action \(title)") self.customActionWhenTapped = performAction super.init() } // MARK: Overrides override var activityType: UIActivityType? { return customActivityType } override var activityTitle: String? { return activityName } override class var activityCategory: UIActivityCategory { return .share } override var activityImage: UIImage? { return UIImage(named: activityImageName) } override func canPerform(withActivityItems activityItems: [Any]) -> Bool { return true } override func prepare(withActivityItems activityItems: [Any]) { // Nothing to prepare } override func perform() { customActionWhenTapped() }}