前回の続き

今回は、Toolbarの表示です。

サンプル: https://github.com/stack3/UINavigationControllerSamples

サンプルを起動しToolbarを選択すると以下の画面が表示されます。画面下にToolbarが表示されています。

01

Nextボタンを押すとToolbarが消えます。

02

ちなみに最初の画面に戻るとToolbarが表示されたままになります。これを表示しない方法についても説明します。

STShowToolbarViewControllerクラス

Toolbarを表示している画面です。

Toolbarボタンの初期化

viewDidLoadでToolbarに表示ボタンの初期化を行っています。

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // Nextボタンを押した時のイベント
    [_nextButton addTarget:self action:@selector(didTapNextButton) forControlEvents:UIControlEventTouchUpInside];
    //
    // Toolbarボタン(UIBarButtonItem)の生成
    //
    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
                                                                               target:self
                                                                               action:@selector(didTapAddButton)];
    UIBarButtonItem *deleteButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash
                                                                                  target:self
                                                                                  action:@selector(didTapDeleteButton)];
    // ボタンどうしの間隔を作るためのUIBarButtonItem
    UIBarButtonItem *flexibleSpaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                                                                                       target:nil
                                                                                       action:nil];
    // ボタンの並び順に配列にしてtoolbarItemsに設定
    self.toolbarItems = @[addButton, flexibleSpaceItem, deleteButton];
}

Toolbarに表示するボタンはUIButtonではなくUIBarButtonItemであることに注意。またUIBarButtonItemはUIViewのSubclassではないことにも注意してください。

UIBarButtonSystemItemFlexibleSpaceについては次の記事で詳しく説明します。

Toolbarの表示

viewWillAppearでToolbarが表示されるようにします。

- (void)viewWillAppear:(BOOL)animated
{
    [self.navigationController setToolbarHidden:NO animated:YES];
}

setToolbarHidden:animatedをviewWillAppearで呼ぶと見栄えが綺麗だと思います。

animatedパラメータに指定する値で以下のように見栄えが変わります。

animated:NOの場合、画面遷移中にToolbarが完全に表示され、前の画面も覆います。

04

animated:YESの場合、次の画面にのみ表示された状態でスライドしてきます。

06

どっちにするかは好みで良いと思いますが、気をつけないと画面遷移中にToolbar部分が黒くなり見栄えが悪くなることがあります。これについては後述します。

次の画面へ遷移

Nextボタンを押すとSTHideToolbarViewControllerへ遷移するようにします。

- (void)didTapNextButton
{
    STHideToolbarViewController *con = [[STHideToolbarViewController alloc] init];
    [self.navigationController pushViewController:con animated:YES];
}

STHideToolbarViewControllerクラス

いったんToolbarを表示してしまうと、次の画面へ遷移しても表示されたままになってしまいます。

この画面では以下のようににしてToolbarが非表示になるようにしています。

- (id)init
{
    self = [super initWithNibName:@"STHideToolbarViewController" bundle:nil];
    if (self) {
        self.title = @"Hide Toolbar";
        // この画面がpushViewControllerされたらToolbarを非表示にする
        self.hidesBottomBarWhenPushed = YES;
    }
    return self;
}

UIViewController#hidesBottomBarWhenPushedプロパティをYESにしておくと、このViewControllerがUINavigationControllerへpushViewControllerされたとき、Toolbarが非表示になります(前の画面でToolbarが表示されていた場合)。

hidesBottomBarWhenPushedは、設定的なプロパティであって、このプロパティを設定した瞬間にToolbarが非表示になるわけではないことに注意してください。またhidesBottomBarWhenPushedがNOのときは、Toolbarを非表示にする処理を行わないというだけで、pushViewControllerされたときにToolbarが表示されるわけではないことにも注意です。

Toolbarの表示・非表示する画面が混在する場合

さて最初にちらっと書きましたが、この画面から最初の画面に戻るとToolbarが表示されたままになっています。

Toolbarの表示で面倒なのは一回どこかの画面で表示してしまうと、なにもしない限り他の画面に遷移した時も表示されたままになってしまうことです。注意しないと意図しない画面でToolbarが表示されるということになりかねません。

そこで解決するためのアプローチをいくつか示したいと思います。

すべてのViewControllerでhidesBottomBarWhenPushedを設定する

デフォルトではhidesBottomBarWhenPushedはNOです。よって他の画面でToolbarが表示されて、元の画面に戻ってくるとToolbarが表示されたままになります。

Toolbarを表示すべきでない画面のViewControllerはすべてhidesBottomBarWhenPushedをYESに設定するというのが1つのアプローチです。

ただ全部に設定するのは面倒ですし、設定漏れが起きかねないのが欠点です。

viewWillAppear/viewWillDisappearでToolbarを表示・非表示する

Toolbarを表示すべき画面のViewControllerのviewWillAppearでToolbar表示、viewWillDisappearでToolbar非表示するという方法もあります。

- (void)viewWillAppear:(BOOL)animated
{
    [self.navigationController setToolbarHidden:NO animated:YES];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [self.navigationController setToolbarHidden:YES animated:YES];
}

Toolbar表示する画面が一部だけの場合は、この方法が楽かもしれません。その画面だけ上記のコードを埋めれば良いからです。

ただし画面Aと画面B、両方で上記のコードが埋め込まれていると以下のように画面遷移の時に前の画面のToolbar部分が黒くなります(iOS 6で確認)。

03-1

以下のようにすると黒くなる現象を解消することができます。ちょっとトリッキーですが。

- (void)viewWillAppear:(BOOL)animated
{
    // animated:NOにする
    [self.navigationController setToolbarHidden:NO animated:NO];
}

- (void)viewWillDisappear:(BOOL)animated
{
    // animated:YESにする
    [self.navigationController setToolbarHidden:YES animated:YES];
}

以上、Toolbar表示の説明でした。

その3へ続く