2012年4月12日木曜日

UIPopoverControllerを使う際の注意すること

先日、UIPopoverControllerの使い方を書きましたが
そのままではいくつものPopoverControllerが生成されてしまいます。
// Type4ボタンタップ時
- (IBAction) tapAction:(id)sender
{
    UIImagePickerController *ipc = [[[UIImagePickerController alloc] init] autorelease];
    ipc.delegate = self;
    ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    
    // Popoverのインスタンス生成
    UIPopoverController *popover = [[UIPopoverController alloc]
                                    initWithContentViewController: ipc];

    // Popoverを表示する
    [popover presentPopoverFromBarButtonItem:sender
                permittedArrowDirections:UIPopoverArrowDirectionAny
                animated:YES];
}

実際に上記のコードで起動してみると
左の画面は Type4 ボタンを1回だけクリックした状態、
右の画面は Type4 ボタンを10回くらいクリックした状態です。

右の画面では PopoverController の周りが黒く表示されているのがわかると思います。
これは Type4 ボタンをタップした際にその都度 PopoverController を生成しているからです。

これを回避するために、いくつかコードの修正を行います。

ViewController.h
@interface ViewController : UIViewController
{
    UIPopoverController *popover;
}

ViewController.m
// Type4ボタンタップ時
- (IBAction) tapAction:(id)sender
{
    // Popoverの確認・開かれている場合は一度閉じる
    if (popover) {
        if ([popover isPopoverVisible]) {
            [popover dismissPopoverAnimated:YES];
        }
    }

    UIImagePickerController *ipc = [[[UIImagePickerController alloc] init] autorelease];
    ipc.delegate = self;
    ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    
    // Popoverのインスタンス生成(ココが違う)
    popover = [[UIPopoverController alloc]
                                    initWithContentViewController: ipc];

    // Popoverを表示する
    [popover presentPopoverFromBarButtonItem:sender
                permittedArrowDirections:UIPopoverArrowDirectionAny
                animated:YES];
}

上記のように popover を予め宣言しておき、それを使い回しできるようにしておきます。
こうすることで Type4 ボタンをいくらタップしても影響がでることはないと思います。
ここでは記載してませんが、dealloc や viewDidunload 等で popover を 破棄した方がいいと思います。
他にも UIPopoverControllerDelegate を実装しておくことで Popover 部分以外をタップしたことによる画面の閉じる処理を通知してくれます。ここで破棄処理をいれておいてもいいかもしれません。
- (BOOL)popoverControllerShouldDismissPopover: popoverController
閉じる前に呼び出される。NOを返すことで画面が閉じないようになる
- (void)popoverControllerDidDismissPopover: popoverController
閉じた後に呼び出される





0 件のコメント:

コメントを投稿