CS193p - Lecture 7

iTunes U スタンフォード大学のiOSアプリ開発講義のLecure 7(iPad)の講義メモです。

UIToolBar

■作成方法

・通常のツールバー:

  1. storyboardでToobar(UIToolbar)をViewの中にドラッグ
  2. Bar Button Item(UIBarButton)をToolbarの中にドラッグ
  3. アウトレットやアクションを接続

・UINavigationControllerのツールバー

XcodeのAttributes Inspectorで、□ Shows Toolbar をチェック

(toolbarHiidenプロパティがNOからYESに変更される)

 

UISplitViewController (7:36〜)

iPad専用の左右分割画面のViewController

■内部のView Controller

@property (nonatomic, copy) NSArray *viewControllers; // 0:左(マスタ), 1:右(ディテール)

タイプがcopyなので、コピーされるがNSArrayなので設定後に内容の変更は出来ない。
viewDidLoadメソッド内でdelegateの設定をして、回転をさせてマスタが非表示になったあとに表示させるボタンを割り当てたりする。

■左側のMVCの制御

- (BOOL)splitViewController:(UISplitViewController *)sender
   shouldHideViewController:(UIViewController *)master
              inOrientation:(UIInterfaceOrientation)orientation
{
    return YES; //常に隠す
    return NO;  //常に表示
    return UIInterfaceOrientationIsPortrait(orientation); //縦向きの時に隠す(デフォルト)
}

■UISplitViewControllerDelegate

左側のMVCが隠れた時には右側のツールバーのボタンにポップオーバーで表示させるボタンを設定するdelegateを追加する。

- (void)splitViewController:(UISplitViewController *)sender
     willHideViewController:(UIViewController *)master
          withBarButtonItem:(UIBarButtonItem *)barButtonItem
    forPopoverController:(UIPopoverController *)popover
{
    barButtonItem.title = @“Master”; // use a better word than “Master”!
    //setSplitViewBarButtonItem:は自分で実装
    [detailViewController setSplitViewBarButtonItem:barButtonItem];
}

また、ボタンが不要になったら削除するdelegateも追加する。

- (void)splitViewController:(UISplitViewController *)sender
     willShowViewController:(UIViewController *)master
  invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    [detailViewController removeSplitViewBarButtonItem:nil];
}

典型的な、setSplitViewBarButtonItem:メソッド

- (void)setSplitViewBarButtonItem:(UIBarButtonItem *)barButtonItem {
    UIToolbar *toolbar = [self toolbar]; // アウトレットか作成されたツールバー
    NSMutableArray *toolbarItems = [toolbar.items mutableCopy];

    if (_splitViewBarButtonItem) [toolbarItems removeObject:_splitViewBarButtonItem];
    // 既存のツールバーの左端にボタンを設置
    if (barButtonItem) [toolbarItems insertObject:barButtonItem atIndex:0];
    toolbar.items = toolbarItems;
    _splitViewBarButtonItem = barButtonItem;
}

■右側のMVCの更新のされ方

1) ターゲット/アクションでの更新

マスタView ControllerでディテールMVCを取得して更新する。

id detailViewController = [[self.splitViewController viewControllers] lastObject];
[detailViewController 送信メッセージ];

2) Segueで更新

ディテールMVCをsegueで置き換える。この時忘れずにツールバーも置き換える。

 

Popover (23:51〜)

ポップオーバーは、UIViewContollerではないが枠内にMVCを表示させる。

prepareForSegue:sender: で受け取る引数は、isKindOf:UIStoryboardPopoverSegue
このUIStoryboardPopoverSegueは、(UIPopoverController *)popoverControllerというプロパティを持っている。

ポップオーバーは、ポップオーバーの枠外をクリックすると自動的に消えるようになっているが、次のプロパティで特定のビューはクリックされてもポップオーバーが消えないように指定できる。

@property (nonatomic, copy) NSArray *passthroughViews;

■ポップオーバーのサイズを設定する3つの方法
1) XcodeのAttributes InspectorでView Controllerのポップオーバーサイズを指定
2) プロパティを設定
    @property (nonatomic) CGSize contentSizeForViewInPopover;
3) ポップオーバーのコントローラにメッセージ送信
    - (void)setPopoverContentSize:(CGSize)size animated:(BOOL)animated;

 

Universal Applications (32:50〜)

ユニバーサルアプリケーションとは、iPhoneとiPadで動く単一バイナリイメージの単一アプリケーションのこと。
ユニバーサルアプリケーションでは、View Controllerなど多くのものを共有する。

■既存のプロジェクトをユニバーサルアプリケーションに変更する方法

プロジェクトのターゲットの画面にあるsammaryタブでDeviceをUniversalに設定変更する。

■コード内でデバイスを判断する方法

    BOOL iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);

もしくは、例えばコントローラ内で、split viewが存在するかどうかを

    self.splitViewControllerでチェックする
もしくは、Viewが画面上にあるかどうかをチェックする。
    if (self.view.window) ... //iPadは画面が広いのでViewが画面上にあることが多い
もしくは、画面のサイズをチェックする。
    CGRect screenBounds = [[UIScreen mainScreen] bounds]; // 単位はポイント
もしくは、解像度をチェックする。
    @property (CGFloat) contentScaleFactor //RatinaのiPhoneは、1ポイントが2ピクセル

 

デモ(ユニバーサルアプリへの変更) (36:33〜)

iPhoneアプリからユニバーサルアプリへ変更

■変更手順

1. ターゲットデバイスをユニバーサルに変更

2. iPad用のstoryboardを新規作成

3. 作成したstoryboardをiPadのstoryboardとして割当

UISplitViewControllerの実装

storyboardでView Controllerを設置して接続やクラスなどを設定。

■回転時のmasterMVCの表示のされ方を設定

縦向きになったら、masterMVCを隠して、masterMVCをポップオーバーで表示するボタンを出す。

<前の記事 

グラフ電卓の出来上がり具合 -   CS193p - Lecture 8 次の記事>