8

カスタム アクティビティを標準のアクティビティ (印刷、メール、FaceBook など) に実装しようとしていますが、今のところ、標準の印刷 (AirPrint 用) と独自のカスタム印刷のみが直接的な方法で必要です。カスタムクラスのメソッドが呼び出されないため、明らかに基本的なものが欠けています。今のところ、呼び出しシーケンスを把握し、フレームワークを機能させるための NSLog ステートメントしかありません。

以下は、カスタム アクティビティ クラスのテスト コードです。

//  PrintActivity.h

#import <UIKit/UIKit.h>

@interface PrintActivity : UIActivity

@end

そして、.m

#import "PrintActivity.h"

@interface PrintActivity ()
@property (nonatomic, strong) UIWebView *dummyWebView;
@end

@implementation PrintActivity

- (NSString *)activityType {
    NSLog(@"activityType");
    return @"MetriScan Print";
}

- (NSString *)activityTitle {
    NSLog(@"activityTitle");
    return @"MetriScan\nPrint";
}

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

- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems {
    NSLog(@"canPerformWithActivityItems");
    return YES;
}

- (void)prepareWithActivityItems:(NSArray *)activityItems {
    NSLog(@"prepareWithActivityItems");
}

- (void)performActivity {
    NSLog(@"Do the actual printing here");
// My custom code here

}

そして、これはメイン ルーチンでの呼び出しです。

- (IBAction)printReport:(UIBarButtonItem *)sender {
    NSLog(@"Print Report");

    PrintActivity *metriscanPrint = [[PrintActivity alloc] init];

    UIViewPrintFormatter *printFormatter = [self.webView viewPrintFormatter];

    NSArray *activityItems = [NSArray arrayWithObjects:printFormatter, nil];
    NSArray *appActivities = [NSArray arrayWithObjects:metriscanPrint, nil];
    UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:appActivities];
    //activityController.excludedActivityTypes = [NSArray arrayWithObjects:UIActivityTypePostToFacebook, UIActivityTypePostToTwitter, UIActivityTypePostToWeibo, UIActivityTypeMail, UIActivityTypeMessage, nil];
    activityController.completionHandler = ^(NSString *activityType, BOOL completed) {
        sender.enabled = YES;
    };

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        [self presentViewController:activityController animated:YES completion:nil];
    } else {
        sender.enabled = NO;
        self.printPop = [[UIPopoverController alloc] initWithContentViewController:activityController];
        [self.printPop presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
    }

前述したように、カスタム クラスのメソッドは呼び出されませんが、システムのメール、メッセージ、およびコピー アイコンはアクティビティ シートに表示され、印刷アイコンは表示されません。システムの [印刷] アイコン (および自分のアイコン) だけを期待していました。

ステートメントの一番上のブロックのコメントを外すと (そして NSArray *activityItems ............ をコメント アウトすると)、システム メール、メッセージ、印刷、およびコピーの各アイコンが表示されます。この実験では、独自のフォーマッターを作成してさまざまな方法を組み合わせていると思いますが、それは WWDC 2012 での提案のようでした。

次に、「excludeActivityTypes」の行のコメントを外すと、システムの印刷アイコンのみが表示されます。

これを理解するのに役立つ情報を歓迎します。

そして、私がやりたいことを実行するためのコード例を誰かが知っていれば、それは素晴らしいことです.

編集:コードを作業コードに更新しました。

4

3 に答える 3

7

私はこの 1 週間、UIActivity についても頭を悩ませていましたが、Apple によってより適切に説明され、より多くの機能が追加される必要があります。これを試して:

PrintActivity.h

#import <UIKit/UIKit.h>
@interface PrintActivity : UIActivity
@end

PrintActivity.m

#import "PrintActivity.h"

@implementation PrintActivity

- (NSString *)activityType
{
   return @"MetriScan.Print";
}

- (NSString *)activityTitle
{
    return @"Print MtriScan";
}

- (UIImage *)activityImage
{   
    //***** Note: I recommend using two sizes, as the iPad's UIActivity image size differs from 
    //***** the iPhone's. Also, create @2x sizes for Retina compatible devices. So you will     
    //***** have a total of 4 images.
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
    return [UIImage imageNamed:@"test_72.png"];
}

    return [UIImage imageNamed:@"test_57.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 your custom print code should go

}

@end

次の 2 つのファイルも作成することを忘れないでください。

PrintProvider.h

#import <UIKit/UIKit.h>

@interface PrintProvider : UIActivityItemProvider <UIActivityItemSource>

@end

PrintProvider.m

#import "PrintProvider.h"

@implementation PrintProvider

#pragma mark - UIActivityItemSource

- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
    NSLog(@"%s",__FUNCTION__);
    NSLog(@"%@", activityType);
    return [super activityViewController:activityViewController itemForActivityType:activityType];
}

@end  

これで、最終的に次のように呼び出すことができます。

- (IBAction)printReport:(UIBarButtonItem *)sender {


CustomProvider *customProvider =
                [[CustomProvider alloc]init];
                NSArray *items = [NSArray arrayWithObjects:customProvider,nil];

                CustomActivity *ca = [[CustomActivity alloc]init];

                UIActivityViewController *activityVC =
                [[UIActivityViewController alloc] initWithActivityItems:items
                                                  applicationActivities:[NSArray arrayWithObject:ca]];

                activityVC.excludedActivityTypes = @[UIActivityTypePostToWeibo,
                UIActivityTypeAssignToContact,UIActivityTypeCopyToPasteboard,
                UIActivityTypeSaveToCameraRoll,UIActivityTypeMail,UIActivityTypePostToTwitter,
                UIActivityTypePostToFacebook,UIActivityTypeMessage];

                activityVC.completionHandler = ^(NSString *activityType, BOOL completed)
                {
                    NSLog(@" activityType: %@", activityType);
                    NSLog(@" completed: %i", completed);
                };

                    self.popoverController = [[UIPopoverController alloc] initWithContentViewController:activityVC];

                    CGRect rect = [[UIScreen mainScreen] bounds];

                    [self.popoverController
                     presentPopoverFromRect:rect inView:self.view
                     permittedArrowDirections:0
                     animated:YES];
}
于 2012-10-07T18:18:17.640 に答える
3

@ troop231-すばらしい答えで、とても役に立ちました。

私が追加する唯一のことは、操作の完了を通知することです。そうしないと、完了ルーチンが呼び出されず、ポップオーバーが閉じられません。何かのようなもの:

- (void)performActivity {
    NSLog(@"Do the actual activity here");
    // My custom code here

    [self activityDidFinish:YES];  // indicate completion here!!
}
于 2013-03-21T21:46:18.613 に答える