web-dev-qa-db-ja.com

ポップオーバーではなくiPadでモーダルに表示されるUIActivityactivityViewController

IOS 6でカスタマーUIActivityサブクラスを使用する場合、最初のUIActionViewControllerのビューからアクションが選択されたときに表示されるカスタムビューコントローラーを指定できます。これを行うには、UIActivityサブクラスのactivityViewControllerメソッドからカスタムビューコントローラーへの参照を返します。

IActivityクラスリファレンス によると:

activityViewController

このメソッドのデフォルトの実装はnilを返します。ビューコントローラを使用して追加のUIを提供するサブクラスは、このメソッドをオーバーライドして、そのビューコントローラを返すことができます。このメソッドが有効なオブジェクトを返す場合、システムはperformActivityメソッドを呼び出す代わりに、返されたViewControllerを提示します。 iPadでは、ViewControllerはポップオーバー内に表示されます。 iPhoneおよびiPodtouchでは、ビューコントローラはモーダルで表示されます。

カスタムビューコントローラーは、カスタムUIを備えたビューを提供し、それらのビュー内でのユーザー操作を処理する必要があります。アクティビティが完了したら、ViewControllerを自分で閉じないでください。代わりに、activityDidFinish:メソッドを呼び出して、システムにそれを却下させます。

最初の段落の最後にあるビットに注意してください:iPadでは、ViewControllerはポップオーバーの中に表示されます。 iPhoneおよびiPodtouchでは、ビューコントローラはモーダルで表示されます。

ただし、iPadでは、UIActivityViewControllerをどのように提示しても(モーダルまたはポップオーバーを介して)、activityViewControllerによって返されるビューコントローラーは常にモーダルで表示されます。ポップオーバーを介してプレゼンテーションを行うと、却下されたとは見なされないため、クラッシュが発生します。

私は何が間違っているのですか?これはiOS6のバグですか?


更新:これは問題を説明する簡単なXcodeプロジェクトです。自由にクローンを作成して、どこが間違っているのかを確認してください: github.com/simonwhitaker/GSActivityDemo

13
Gujamin

UIActivityViewControllerについて話しているので、これはユーザーが利用できるアクティビティを示すビューです。 Apple次のように述べてください...

アプリは、このView Controllerの構成、表示、および非表示を担当します。 View Controllerの構成には、ViewControllerが動作するデータオブジェクトの指定が含まれます。 (アプリがサポートするカスタムサービスのリストを指定することもできます。)View Controllerを表示するときは、現在のデバイスに適切な手段を使用して指定する必要があります。 iPadでは、ポップオーバーでViewControllerを提示する必要があります。 iPhoneおよびiPodtouchでは、モーダルで表示する必要があります。

最後の行は、ビューの表示方法を処理する必要があることを示しているため、コードがiPadで実行されているかどうかを確認し、それに応じてUIPopoverを使用します。ここで確認できるように... https://github.com/bufferapp/buffer-uiactivity/blob/master/BufferUIActivity/Views/FirstViewController.m 次のメソッド内。

-(IBAction)openUIActivityView:(id)sender {

    NSString *text = @"Hello world";
    NSString *url = @"http://bufferapp.com";


    NSArray *activityItems = @[text, url];

    BufferUIActivity *bufferActivity = [[BufferUIActivity alloc] init];

    UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:@[ bufferActivity ]];


    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        [self presentViewController:activityView animated:YES completion:^{

        }];
    } else {
        // Change Rect to position Popover
        self.popup = [[UIPopoverController alloc] initWithContentViewController:activityView];
        [self.popup presentPopoverFromRect:CGRectMake(self.view.frame.size.width/2, self.view.frame.size.width/2, 100, 100) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }

}
23
AndyDev

ポップオーバーに表示されないアクティビティビューコントローラーの問題はバグであり、ドキュメントには正しい意図が反映されていると思います。ただし、このATMを回避する方法がわかりません。

ただし、ViewControllerを閉じることに関する部分は別の問題です。 -[UIActivity activityViewController]から戻ってきたビューコントローラを却下することは想定されていませんが、あなたは提示したポップオーバーを却下する責任があります。これにより、カスタムViewControllerも階層から削除されます。 (このように機能するため、通常はカスタムビューコントローラーをポップオーバーに表示する必要があると思います。)

あなたの例 アプリのコードを使用した例を次に示します。

UIActivityViewController *vc = [[UIActivityViewController alloc] initWithActivityItems:activityItems
                                                                 applicationActivities:applicationActivities];

vc.completionHandler = ^(NSString *activityType, BOOL completed){
  [self.activityPopoverController dismissPopoverAnimated:YES];
};
3
alloy


iOS 7でも同じ問題が発生しました。ポップオーバーにカスタムビューを表示する解決策は、-(void)performActivityで返すのではなく、-(UIViewController *)activityViewControllerメソッドで作成して表示することです。 。

このリンクの下の私の質問/回答でサンプルコードを見ることができます:
ポップオーバーとしてのiOS 7カスタムUIActivity

1
Damian Sch.