iPhoneでUIActionSheet、iPadではUIPopoverControllerを表示する

iPadiPhoneのユニバーサル対応を試して、
UIPopoverとUIActionSheetを使い分ける事を試してみる。
大分ニッチな気がしますが、

今回ははじめから、ユニバーサルを選んでつくります。

チェックボックスのDevice familyで早速「universal」を選びます。


まずコードを読んでみる。

iPadTestAppDelegate.mファイルをみてみると。

application didFinishLaunchingWithOptionsメソッドで
iPhoneiPadの分岐処理が自動で作られている。

一つのViewControllerを使うが、
iPhoneだったらiPhoneのxibファイル
iPadだったらiPadのxibファイルを読み込むという仕組みですね。

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    
    //iphoneの場合
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.viewController = [[[iPadTestViewController alloc] initWithNibName:@"iPadTestViewController_iPhone" bundle:nil] autorelease];
    }
    //iPadの場合
    else
    {
        self.viewController = [[[iPadTestViewController alloc] initWithNibName:@"iPadTestViewController_iPad" bundle:nil] autorelease];
    }
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}


今回はUIToolBarを追加して、その中にボタンを設置してみます。
iPhoneならボタンを押すとアクションシートが出て来るように、
iPadならUIPopoverControllerが出る様にしてみる。

UIActionSheetの場合は、キャンセルとカメラボタンが、
UIPopoverControllerの場合はフォトライブラリを開くボタンだけがでるようにする。


まずはxibファイルにUIToolBarを配置する。


iPhone.xibもiPad.xibもツールバーをおいて、
中のBarButtonItemはidentifierをCameraにしておく


iPhone用のxibファイルを開き。
これでUIToolBarからOutletをiPadTestViewControllerに引っ張る
UIBarButonItemからはActionをiPadTestViewControllerに引っ張る。

こんな感じです。

#import <UIKit/UIKit.h>

@interface iPadTestViewController : UIViewController

@property (retain, nonatomic) IBOutlet UIToolbar *myOutletToolbar;
 - (IBAction)myActionCameraBtn:(id)sender;

@end

あとは、iPad用のxibファイルを開くと、
作成済みのOutletとActionがFIle'sOwnerにあるので、
これをObjectsのToolbarとBarButtonItemにそれぞれ繋げる



これで、2つのxibファイルのOutletとActionがつながる先を、
1つのViewControllerに設定できた。

iPadTestViewController.hに
UIActionSheetDelegateを追加しておく

@interface iPadTestViewController : UIViewController
//追加
<UIActionSheetDelegate>
@property (retain, nonatomic) IBOutlet UIToolbar *myOutletToolbar;
 -(IBAction)myActionCameraBtn:(id)sender;

@end

次は早速Cameraボタンを押した時の分岐に取りかかる。

まずappDelegate.mからiphone,ipad分岐コードをもってきて、
iPadTestViewController.mのmyActionCameraBtn内に記述する。

 - (IBAction)myActionCameraBtn:(id)sender 
{
    
    //iphoneの場合
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
    {
        //UIActionSheetを初期化して準備する
        UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Menu"
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                             destructiveButtonTitle:nil
                                                  otherButtonTitles:@"camera", nil];
        //UIActionSheetを表示する
        [sheet showFromToolbar:myOutletToolbar];
    }
    //iPadの場合
    else
    {
    }
}

これでiPhoneシミュレータを起動、BarButtonを押すとこんな感じ。
まだカメラを選んでもなにも起きない。


iPadTestViewController.hに、
UIImagePickerControllerDelegateと、UIImagePickerのプロパティを追記

#import <UIKit/UIKit.h>

@interface iPadTestViewController : UIViewController
<UIActionSheetDelegate,UIImagePickerControllerDelegate>
@property (retain, nonatomic) IBOutlet UIToolbar *myOutletToolbar;
@property (retain,nonatomic)UIImagePickerController *picker;
- (IBAction)myActionCameraBtn:(id)sender;

@end

iPadTestViewController.mに@synthesizeを追記

#import "iPadTestViewController.h"

@implementation iPadTestViewController
@synthesize myOutletToolbar;
@synthesize picker;


次はmyActionCameraBtnを以下の様に編集する。
結構長いので注意。実はPopoverControllerを出したかっただけなので、
目的は終了してしまって。メソッド化したい人はして下さい。
僕はしません。

 - (IBAction)myActionCameraBtn:(id)sender 
{
    //カメラを初期化
    picker = [[UIImagePickerController alloc]init];        
    //カメラ関係のデリゲートの通知先を自分に設定
    picker.delegate = (id)self;    
    
    //カメラ起動可能?
    if( [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){

        //iphoneの場合
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) 
        {
            //iPhoneならカメラを起動できるようセット
            picker.sourceType = UIImagePickerControllerSourceTypeCamera;    
            
            //UIActionSheetを初期化して準備する
            UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Menu"
                                                               delegate:self
                                                      cancelButtonTitle:@"Cancel"
                                                 destructiveButtonTitle:nil
                                                      otherButtonTitles:@"camera", nil];
            //UIActionSheetを表示する
            [sheet showFromToolbar:myOutletToolbar];
        }
        //iPadの場合
        else
        {
            picker.sourceType = UIImagePickerControllerSourceTypeCamera;    
            
            //UIPopoverControllerを初期化
            UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:picker];
            [popover presentPopoverFromBarButtonItem:[[myOutletToolbar items] objectAtIndex:0]
                            permittedArrowDirections:UIPopoverArrowDirectionRight
                                            animated:YES];
        }
    }
    //カメラを使えない場合
    else
    {   
        picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;            
        //そしてiPhoneの場合     
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
        {            
            //UIActionSheetを初期化して準備する
            UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Menu"
                                                               delegate:self
                                                      cancelButtonTitle:@"Cancel"
                                                 destructiveButtonTitle:nil
                                                      otherButtonTitles:@"camera", nil];
            //UIActionSheetを表示する
            [sheet showFromToolbar:myOutletToolbar];           
        }
        //iPadの場合
        else
        {
            //UIPopoverControllerを初期化
            UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:picker];
            [popover presentPopoverFromBarButtonItem:[[myOutletToolbar items] objectAtIndex:0]
                            permittedArrowDirections:UIPopoverArrowDirectionDown
                                            animated:YES];    
        }
    }
    [picker release];        
}

これでiPadシミュレータを起動した際はカメラボタンの動作がこうなればOK