How can I create a custom UIActivity
in iOS?
如何在iOS中创建自定义的UIActivity ?
The reason I want this is to add a Review App button in one of my apps that takes the user to the review section in the App Store. How can I create such a custom UIActivity
?
我想要这个的原因是在我的一个应用程序中添加一个评论应用程序按钮,它将用户带到App Store的Review部分。如何创建这样一个自定义的UIActivity?
4 个解决方案
#1
169
First, create the files. I chose to name mine ActivityViewCustomActivity
首先,创建的文件。我选择了我的ActivityViewCustomActivity。
Make ActivityViewCustomActivity.h look like this:
使ActivityViewCustomActivity。h是这个样子:
#import <UIKit/UIKit.h>
@interface ActivityViewCustomActivity : UIActivity
@end
Make ActivityViewCustomActivity.m look like this:
使ActivityViewCustomActivity。m是这个样子:
#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
这就是我的图像的样子:这里是我做的。psd:——恶意链接被删除——这里是原来的250像素。
Now in your view controller do this:
在你的视图控制器中这样做:
#import "ActivityViewCustomActivity.h"
And now wherever you want to display your UIActivityViewController
:
现在无论你想在哪里显示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];
}
#2
22
Here is my Swift Version - I needed multiple custom actions so I created this class. No need for delegates or protocols.
这是我的Swift版本——我需要多个自定义操作,所以我创建了这个类。不需要委托或协议。
1. Add the custom Class
1。添加自定义类
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
我将它附加到UIBarButtonItem,它调用下面的内容。
@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)
}
#3
8
My Swift 3 Implementation based off of DogCoffee's:
基于DogCoffee的Swift 3实现:
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()
}
}
#4
1
Here's an example of putting up an email composer interface using the -activityViewController method of UIActivity. This shows how to put up a UIKit viewController or your own custom viewController for whatever purpose you choose. It supplants the -performActivity method.
这里有一个例子,使用-activityViewController方法来建立一个电子邮件编写器接口。这说明了如何为您选择的任何目的建立一个UIKit视图控制器或您自己的自定义视图控制器。它取代了-performActivity方法。
#import <MessageUI/MessageUI.h>
#import <UIKit/UIKit.h>
@interface EPSuggestionsActivity : UIActivity <MFMailComposeViewControllerDelegate>
@end
@implementation EPSuggestionsActivity
....
- (UIViewController *)activityViewController{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
NSString *emailAddress = @"developer@apple.com";
NSArray *toRecipients = @[emailAddress];
[picker setToRecipients:toRecipients];
[picker setSubject:@"Suggestions"];
return picker;
}
#pragma mark - MFMailComposeViewControllerDelegate Method
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self activityDidFinish:YES]; // Forces the activityViewController to be dismissed
}
@end
Notice that -activityDidFinish is called from the mail composer delegate after the user has dismissed the email interface. This is required to get the UIActivityViewController interface to disappear. If you write your own viewController it will need a delegate method that it calls when finished and you will have to make your subclass of UIActivity the delegate.
注意,在用户解除邮件接口后,从邮件编写器委托调用-activityDidFinish。这需要让UIActivityViewController接口消失。如果你编写自己的视图控制器,它需要一个委托方法,它在完成时调用它,你必须让你的UIActivity的子类成为委托。
#1
169
First, create the files. I chose to name mine ActivityViewCustomActivity
首先,创建的文件。我选择了我的ActivityViewCustomActivity。
Make ActivityViewCustomActivity.h look like this:
使ActivityViewCustomActivity。h是这个样子:
#import <UIKit/UIKit.h>
@interface ActivityViewCustomActivity : UIActivity
@end
Make ActivityViewCustomActivity.m look like this:
使ActivityViewCustomActivity。m是这个样子:
#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
这就是我的图像的样子:这里是我做的。psd:——恶意链接被删除——这里是原来的250像素。
Now in your view controller do this:
在你的视图控制器中这样做:
#import "ActivityViewCustomActivity.h"
And now wherever you want to display your UIActivityViewController
:
现在无论你想在哪里显示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];
}
#2
22
Here is my Swift Version - I needed multiple custom actions so I created this class. No need for delegates or protocols.
这是我的Swift版本——我需要多个自定义操作,所以我创建了这个类。不需要委托或协议。
1. Add the custom Class
1。添加自定义类
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
我将它附加到UIBarButtonItem,它调用下面的内容。
@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)
}
#3
8
My Swift 3 Implementation based off of DogCoffee's:
基于DogCoffee的Swift 3实现:
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()
}
}
#4
1
Here's an example of putting up an email composer interface using the -activityViewController method of UIActivity. This shows how to put up a UIKit viewController or your own custom viewController for whatever purpose you choose. It supplants the -performActivity method.
这里有一个例子,使用-activityViewController方法来建立一个电子邮件编写器接口。这说明了如何为您选择的任何目的建立一个UIKit视图控制器或您自己的自定义视图控制器。它取代了-performActivity方法。
#import <MessageUI/MessageUI.h>
#import <UIKit/UIKit.h>
@interface EPSuggestionsActivity : UIActivity <MFMailComposeViewControllerDelegate>
@end
@implementation EPSuggestionsActivity
....
- (UIViewController *)activityViewController{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
NSString *emailAddress = @"developer@apple.com";
NSArray *toRecipients = @[emailAddress];
[picker setToRecipients:toRecipients];
[picker setSubject:@"Suggestions"];
return picker;
}
#pragma mark - MFMailComposeViewControllerDelegate Method
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self activityDidFinish:YES]; // Forces the activityViewController to be dismissed
}
@end
Notice that -activityDidFinish is called from the mail composer delegate after the user has dismissed the email interface. This is required to get the UIActivityViewController interface to disappear. If you write your own viewController it will need a delegate method that it calls when finished and you will have to make your subclass of UIActivity the delegate.
注意,在用户解除邮件接口后,从邮件编写器委托调用-activityDidFinish。这需要让UIActivityViewController接口消失。如果你编写自己的视图控制器,它需要一个委托方法,它在完成时调用它,你必须让你的UIActivity的子类成为委托。