如何在 iOS 中创建自定义 UIActivity?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12766300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:37:40  来源:igfitidea点击:

How can I create a custom UIActivity in iOS?

iosobjective-cuiactivityviewcontrolleruiactivity

提问by klcjr89

How can I create a custom UIActivityin iOS?

如何UIActivity在 iOS 中创建自定义?

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 的评论部分。我怎样才能创建这样的自定义UIActivity

回答by klcjr89

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 像素 .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:

现在,无论您想在何处显示您的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];
   }

回答by DogCoffee

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

2 在您的视图控制器中使用

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

回答by johnslay

My Swift 3Implementation based off of DogCoffee's:

我的Swift 3实现基于 DogCoffee 的:

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

回答by Paul Linsay

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.

下面是使用 UIActivity 的 -activityViewController 方法建立电子邮件编辑器界面的示例。这显示了如何为您选择的任何目的放置 UIKit viewController 或您自己的自定义 viewController。它取代了 -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 = @"[email protected]";
    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 界面消失所必需的。如果您编写自己的 viewController,它将需要一个在完成时调用的委托方法,并且您必须将 UIActivity 的子类设为委托。