Problems Adding Custom Activity to Uiactivitycontroller

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")
}

How can I add a ActivityItem to upper activity bar in UIActivityViewController?

In your custom UIActivity subclass you have to simply override one method:

+ (UIActivityCategory)activityCategory
{
return UIActivityCategoryShare;
}

There are to possible categories: action and share.

It's important, this is class method, not instance. Also, it's iOS 7 specific - all action activities are placed in bottom line (if any), then above the share activities and then above AirDrop. So, if you want to get rid of bottom line for example, simply exclude all action activities. If you want to put something in share/action line - override activityCategory. default is UIActivityCategoryShare;

how to add a custom entry in UIActivityViewController

I believe you are asking about two separate things.

UIActivityViewController:

Here's my code in my app.

let vc = UIActivityViewController(activityItems: [shareImage], applicationActivities: [])
vc.excludedActivityTypes = [
UIActivityType.airDrop,
UIActivityType.assignToContact,
UIActivityType.addToReadingList,
//UIActivityType.copyToPasteboard,
//UIActivityType.mail,
//UIActivityType.message,
//UIActivityType.openInIBooks,
//UIActivityType.postToFacebook,
//UIActivityType.postToFlickr,
UIActivityType.postToTencentWeibo,
//UIActivityType.postToTwitter,
UIActivityType.postToVimeo,
UIActivityType.postToWeibo,
UIActivityType.print,
//UIActivityType.saveToCameraRoll
]
present(vc,
animated: true,
completion: nil)
vc.popoverPresentationController?.sourceView = self.view
vc.completionWithItemsHandler = {(activity, success, items, error) in
}

Pay attention to the excludedActiviyTypes code. My app is an image effect app, so I commented out the things I wish to have in the popup - Weibo, print, assignToContact, ReadingList, Vimeo, and TencentWeibo. Here's the thing - I kept the full list of activities for quick reference. (I've never found it on ADC and end up getting it by using code complete.)

UIActivityType is an extended struct, so if you want to go the route of using it this way I think you'll have to (1) subclass UIActivityViewController, (2) write your own extension to UIActivityType, and (3) provide any/all code needed to use a service that isn't listed above.

A Document Provider is what I think you are looking for. Either that, or Universal - sometimes called Deep - Linking. (The links are to Apple documentation for using each.)

I've obviously used UIActivityiewController, but haven't (yet) had any need to these other two.

If you have questions about setting up a UIActivityViewController, post them in the comments. If someone else has a way to "extend" it in any way other than I described, let me know and I'll remove this answer.

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)

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 to add custom buttons to UIActivityViewController?

Well you have to create your own custom UIActivity, in your case for Instagram.

Have a look at this, even if the question is about on how to do it on iOS 6, the solution is exactly the same on iOS 7.

You can also have a look at this project on github, basically is a collection of custom UIActivity for the most common services Instagram included.

Adding an obvious (custom) button to UIActivityViewController

As nevo shalev said you need to subclass UIActivity class

Here is an example:

UrlActivity.h

#import <UIKit/UIKit.h>

@interface UrlActivity : UIActivity

@end

UrlActivity.m:

#import "UrlActivity.h"

@implementation UrlActivity

- (NSString *)activityType
{
return @"your Custom Type";
}

- (NSString *)activityTitle
{
return @"Title to display under your icon";
}

- (UIImage *)activityImage
{
return [UIImage imageNamed:@"your icon.png"];
}

- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
{
// basically in your case: return YES if activity items are urls
}

- (void)prepareWithActivityItems:(NSArray *)activityItems
{
//open safari with urls (activityItems)
}

+(UIActivityCategory)activityCategory
{
return UIActivityCategoryShare; // says that your icon will belong in application group, not in the lower part;
}

@end

And in your main file (after importing UrlActivity.h):

#pragma mark - Share the link
- (IBAction)activityButtonPressed:(id)sender {

NSString *textToShare = @"I just shared this from my App";
// UIImage *imageToShare = [UIImage imageNamed:@"Image.png"];
NSURL *urlToShare = [NSURL URLWithString:@"http://www.google.com"];
NSArray *activityItems = [NSArray arrayWithObjects:textToShare, urlToShare,nil];

// create an array with your custom activity and add it to the activityVC
NSArray *appActivities = [NSArray arrayWithObjects:[[UrlActivity alloc] init]]];
UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:appActivities];
//This is an array of excluded activities to appear on the UIActivityViewController
//activityVC.excludedActivityTypes = @[UIActivityTypeMessage, UIActivityTypeCopyToPasteboard,UIActivityTypeSaveToCameraRoll];
[self presentViewController:activityVC animated:TRUE completion:nil];

}


Related Topics



Leave a reply



Submit