Skip to content

UINavigationBar の背景を画像にする

2010.10.23

ナビゲーションバーの背景を画像にしたい。そうすることによって、アプリケーションの世界観を前面に押し出したい。たとえば「iBooks」のように。たとえば「メモ」のように。

「そんなの簡単。UIImageView を UINavigationBar に insertSubview: atIndex: すればよいだけの話」と思いきや、そうではありませんでした。ある問題があったのです。

今回は、まずその問題を明らかにし、その問題を踏まえた上で、ナビゲーションバーの背景を画像にする方法を紹介します。
NavigationBar with custom background.


ナビゲーションバーの背景を画像にするとき、真っ先に思いつくのが「UINavigationBar に UIImageView を insertSubview: atIndex: する」という方法ではないでしょうか。

// Get navigationBar
UINavigationBar *navigationBar;
navigationBar = navigationController.navigationBar;

// Insert imageView
UIImageView *imageView;
UIImage *image;
image = [[UIImage imageNamed:@"navbar_bg.png"]
    stretchableImageWithLeftCapWidth:0 topCapHeight:1];
imageView = [[UIImageView alloc] initWithImage:image];
[imageView autorelease];
imageView.frame = navigationBar.bounds;
imageView.autoresizingMask = (
    UIViewAutoresizingFlexibleWidth
    | UIViewAutoresizingFlexibleHeight);
[navigationBar insertSubview:imageView atIndex:0];

// Set tintColor of navigationBar
UIColor *tintColor;
tintColor = [UIColor
    colorWithHue:0.774
    saturation:0.521
    brightness:0.618
    alpha:1.000];
navigationBar.tintColor = tintColor;

確かに、上のようにすることで navigationBar の背景が画像になります。

<図1: navigationBar の背景が画像になった様子>

しかし、これだけでは問題があります。navigationController にビューコントローラをプッシュしたりポップしたりすると、タイトルやバーボタンアイテムが画像に隠れてしまうのです。以下の図は、あるビューコントローラをプッシュしたときの様子です。タイトルが隠れてしまっています。右側のバーボタンアイテムも設定したのですが、これも隠れてしまっています。

customNavBarMissingPieces

<図2: タイトルと右側のバーボタンアイテムが隠れてしまった様子>

この問題は、ビューコントローラをプッシュしたりポップしたりする過程で、タイトルやバーボタンアイテムが imageView よりも後ろに潜り込んでしまうことが原因です。

これを回避する方法はいろいろありますが、最も簡単な方法は imageView.layer.zPosition を 0 より小さな値にすることです。これにより、imageView はビューの並びに左右されず、常に一番後ろに表示されるようになります。

レイヤーを扱うことになるので、<QuartzCore/QuartzCore.h> をインポートするのを忘れずに、zPosition を設定する1行を書き足してみましょう。

#import <QuartzCore/QuartzCore.h>
…

// Get navigationBar
UINavigationBar *navigationBar;
navigationBar = navigationController.navigationBar;

// Insert imageView
UIImageView *imageView;
UIImage *image;
image = [[UIImage imageNamed:@"navbar_bg.png"]
    stretchableImageWithLeftCapWidth:0 topCapHeight:1];
imageView = [[UIImageView alloc] initWithImage:image];
[imageView autorelease];
imageView.frame = navigationBar.bounds;
imageView.autoresizingMask = (
    UIViewAutoresizingFlexibleWidth
    | UIViewAutoresizingFlexibleHeight);
imageView.layer.zPosition = -FLT_MAX;
[navigationBar insertSubview:imageView atIndex:0];

// Set tintColor of navigationBar
UIColor *tintColor;
tintColor = [UIColor
    colorWithHue:0.774
    saturation:0.521
    brightness:0.618
    alpha:1.000];
navigationBar.tintColor = tintColor;

これで、タイトルやバーボタンアイテムが隠れる問題は解決です。無事に、タイトルと右側のバーボタンアイテムも見えるようになりました。

Custom Navigation Bar for Sub

<図3: タイトルや右側のバーボタンアイテムも見えるようになった様子>

Advertisements

From → Develop

4 Comments
  1. 画像だけでなく、CAGradientLayerを背景にする場合にもこのエントリの方法が使えました。(navigationBar.layer insertSublayer:atIndex)
    大変参考になり、ありがとうございます!

  2. xcode4.2のstoryboardでアプリをデザインしていますが、Navigation ControllerのNavigationBarの背景を画像にしたいのですが、いろいろやっているのですが上手く行かないです。

    基本的にデザイナーなのでプログラムの知識は無く2日程頑張っても上手く行かず…

    宜しければ何か方法等を教えて下さい。

    宜しくお願いします。

    • Storyboard の編集画面から NavigationBar の背景を弄る方法は、さらっと見た感じ、なさそうでした。コードから弄るしかないようです。
      因に、記事に書いた方法は iOS 4.x でのやり方になります。iOS 5.0 以降だと、UINavigationBar に setBackgroundImage: forBarMetrics: というメソッドが追加されて変更しやすくなっていますので、ちょっと頑張ってコードを書いてみるのは如何でしょうか。
      或は、HTML に明るいならば、HTML でデザインをして、Safari で表示するという方法もありかもしれません。Safari のナビゲーションバーやツールバーを隠すように HTML に書くことができるので、簡単なプロトタイピングができるかもしれませんよ。

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s