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];
}
How can you customize UIActivityViewController to ONLY include custom UIActivity types?
My colleague was able to figure this out. For anyone wondering how to display only the applicationActivities
(custom activities) on the share sheet, this is how I did it.
For activityItems
rather than creating an array of strings, create an array of your custom data objects. Then override the canPerform(withActivityItems activityItems: [Any])
method in your custom UIActivity
(subclass of UIActivity
) to return true if activityItems[o] is CustomItem
. Since your activityItems
are custom, system will not display other apps on the share sheet. That's it.
In the example below, only your CustomUIActivity
will be displayed on the share sheet.
let items = [CustomItem("Hello world")]
let activitySheet = UIActivityViewController(
activityItems: items,
applicationActivities: [
CustomUIActivity()
]
)
class CustomItem {
let value: String
required init(value: String) {
self.value = value
}
func getValue() -> String {
return self.value
}
}
@objc(CustomUIActivity)
class CustomUIActivity: UIActivity {
override class var activityCategory: UIActivity.Category {
return .share
}
override var activityType: UIActivity.ActivityType? {
return .customuiactivity
}
override var activityTitle: String? {
return "Custom"
}
override var activityImage: UIImage? {
return UIImage(named: "custom-icon")
}
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
if activityItems.count == 1 && activityItems[0] is CustomItem {
return true
}
return false
}
var textToShare: String?
override func prepare(withActivityItems activityItems: [Any]) {
if let activityItem = activityItems.first as? CustomItem {
self.textToShare = activityItem.getValue
}
}
override func perform() {
// perform your custom activity with `textToShare`
activityDidFinish(true)
}
}
extension UIActivity.ActivityType {
static let customuiactivity =
UIActivity.ActivityType("com.ceylonese.mobile.customuiactivity")
}
Add custom UIActivity for standard apps
As of iOS 6, there is no way to add a custom UIActivity
item to built-in apps like Photos, Notes, or Safari.
Custom UIActivity
items can only be added to third-party apps.
UIActivity from UIActivityType
Reading through the Apple documentation about this and I read:
“Subclassing Notes
This class must be subclassed before it can be used. The job of an
activity object is to act on the data provided to it and to provide
some meta information that iOS can display to the user. For more
complex services, an activity object can also display a custom user
interface and use it to gather additional information from the user. “
That means you’ll need to create a custom implementation of UIActivity and override its functionality to create the method you wish to use. Like creating a custom implementation of a CollectionViewCell.
UIActivity View Controller with custom row (Like what's App did in edit photo)
You can use an UIAlertController for this:
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancel = UIAlertAction(title: "Cancel"), style: .cancel)
{
_ in
}
alert.addAction(cancel)
let take = UIAlertAction(title: "Take Photo", style: .default)
{
_ in
// TODO Do something
}
alert.addAction(take)
let choose = UIAlertAction(title: "Choose Photo", style: .default)
{
_ in
// TODO Do something
}
alert.addAction(choose)
let deletePhoto = UIAlertAction(title: "Delete Photo", style: .destructive)
{
_ in
// TODO Do something
}
alert.addAction(deletePhoto )
self.present(alert, animated: true, completion: nil)
Related Topics
Take Screenshots in the iOS Simulator
Detect Tap on a Button in Uitableviewcell for Uitableview Containing Multiple Sections
How to Enable Native Resolution For Apps on Iphone 6 and 6 Plus
React Native App Works on Debug Mode, But Not Works Release Mode on Ios
Uistackview Hiding/Unhiding Arrangedsubview Issue
Open Facebook Page in Native Facebook iOS App Via Simple Url Sheme Issue
Remove Alpha Channel in an Image
Swift - Integer Conversion to Hours/Minutes/Seconds
Cell Size Not Updating After Changing Flow Layout'S Itemsize
Nsattributedstring Click Event in Uilabel Using Swift
How to Programmatically Scroll Through a Collection View
Passing Data Between View Controllers
How to Animate Constraint Changes
Converting Nsstring to Nsdate (And Back Again)
How to Change the Push and Pop Animations in a Navigation Based App
How to Navigate Through Textfields (Next/Done Buttons)