【Swift】Navigation Barの設定。バーの色や背景画像をカスタマイズする。(Swift 2.1、XCode 7.2)
2020年6月16日
Navigation Barのアトリビュートインスペクタ
本記事ではNavigation Bar(以下、ナビゲーションバー)の設定について説明する。
Style
ナビゲーションバーの表示スタイルを「Default」、「Black」、「Black Translucent」の中から選択する。
「Default」は白のベタ塗りで、タイトル文字色が黒になる。
「Black」は黒のベタ塗りで、タイトル文字色が白になる。
「Black Translucent」は黒の曇りガラスのような効果によって後ろのビューがぼんやり見えるようになるが、iOS7からは非推奨になっている。曇りガラス効果は「Translucent」のチェックで決めることができるので問題ない。初期状態はチェックが入っている。
下図はStyleに「Default」、Translucentにチェックを入れたナビゲーションバー。初期状態はこの表示になる。
下図はStyleが「Black」、Translucentにチェックを入れたナビゲーションバー。
以降の説明はStyleが「Default」、Translucentにチェックが入っているものとして話を進める。
Bar Tint
ナビゲーションバーの色は白黒に限らず好きな色に変更できる。下図は緑に設定した結果。Bar Tintを設定すると曇りガラスの効果が無くなってしまうのが残念だ。
Shadow Image
Shadow Image(以下、シャドウイメージ)とは、ナビゲーションバーの下にある線のことで、これに画像を設定できる。
しかし、シャドウイメージにファイル名を設定するだけでは画像は表示されない。公式リファレンスには以下のように記述されている。
For a custom shadow image to be shown, a custom background image must also be set with the setBackgroundImage:forBarMetrics: method. If the default background image is used, then the default shadow image will be used regardless of the value of this property.(公式リファレンス)
つまり、ナビゲーションバーに背景画像を設定しないと、シャドウイメージを設定しても無意味ということだ。では背景画像とシャドウイメージを両方設定したら表示されるかを確認しよう。
ナビゲーションバーの背景画像はストーリーボードから設定できないので、UINavigationControllerのサブクラスを作成し、以下のコードのように「画面遷移後の呼び出しメソッド」が呼び出されたタイミングで背景画像とシャドウイメージを設定するようにした。
もちろん、シャドウイメージはストーリーボードから設定しても大丈夫。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// // TestNavigationController.swift // import UIKit class TestNavigationController: UINavigationController, UINavigationControllerDelegate { //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //デリゲート先に自分を設定する。 self.delegate = self } //画面遷移後の呼び出しメソッド func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) { //ナビゲーションバーの背景画像を設定する。 self.navigationBar.setBackgroundImage(UIImage(named: "mokume_test1.png"), forBarMetrics: .Default) //ナビゲーションバーのシャドウイメージを設定する。 self.navigationBar.shadowImage = UIImage(named: "mokume_test2.png") } } |
以下は実際のプレイ動画。背景画像とシャドウイメージが表示された。
ちなみに、以下のコードのように画像未設定のUIImageのインスタンスを背景画像とシャドウイメージに設定すると、ナビゲーションバーが透明になる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// // TestNavigationController.swift // import UIKit class TestNavigationController: UINavigationController, UINavigationControllerDelegate { //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //デリゲート先に自分を設定する。 self.delegate = self } //画面遷移後の呼び出しメソッド func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) { //ナビゲーションバーの背景画像を設定する。 self.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default) //ナビゲーションバーのシャドウイメージを設定する。 self.navigationBar.shadowImage = UIImage() } } |
以下は実際のプレイ動画
Back Image
項目名を見ると一瞬、背景画像の設定だと思ってしまうが、背景画像ではなく「戻るボタン」の画像の設定である。
公式リファレンスに以下の注意文がある。
If you want to customize the back indicator image, you must also set backIndicatorTransitionMaskImage.(公式リファレンス)
つまり、次に説明する「Back Mask」と同時に設定しなければ表示されないということだ。
Back Mask
Back Imageと一緒に設定することで戻るボタンの背景を変えることができる。では以下の赤い矢印の画像をBack ImageとBack Maskに設定し、どのように表示されるか確認してみよう。
下図は実行結果。ボタンの画像が青色になった。
ボタンの画像はナビゲーションバーのtintColorに設定されている色に塗りつぶされてしまうのだ。
そこで、TestNavigationController.swiftを以下のコードに変更して、ナビゲーションバーのボタンの文字色を赤に変更するとどうなるか。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// // TestNavigationController.swift // import UIKit class TestNavigationController: UINavigationController, UINavigationControllerDelegate { //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //デリゲート先に自分を設定する。 self.delegate = self } //画面遷移後の呼び出しメソッド func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) { //ナビゲーションバーのボタンの文字色を赤に変更する。 self.navigationBar.tintColor = UIColor.redColor() } } |
下図は実行結果。ボタンの画像と文字色が赤色になった。
どうやら、「戻るボタン」に設定された画像はレンダリングモードがOriginalにならないためにtintColorと同じになるようだ。
戻るボタンそのものを表示するには以下のコードのようにして、画像のレンダリングモードをAlwaysOriginalに変更しておく。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// // TestNavigationController.swift // import UIKit class TestNavigationController: UINavigationController, UINavigationControllerDelegate { //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //デリゲート先に自分を設定する。 self.delegate = self } //画面遷移後の呼び出しメソッド func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) { //戻るボタンの背景画像を設定する。 self.navigationBar.backIndicatorImage = UIImage(named: "back_button.png")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal) self.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "back_button.png")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal) } } |
下図は実行結果。ボタンの画像が本来の色で表示された。
そもそもボタンの画像はいらないという場合は、以下のコードのように画像未設定のUIImageインスタンスをボタンの画像に設定する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// // TestNavigationController.swift // import UIKit class TestNavigationController: UINavigationController, UINavigationControllerDelegate { //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //デリゲート先に自分を設定する。 self.delegate = self } //画面遷移後の呼び出しメソッド func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) { //戻るボタンの背景画像を非表示にする。 self.navigationBar.backIndicatorImage = UIImage() self.navigationBar.backIndicatorTransitionMaskImage = UIImage() } } |
以下は実行結果。ボタンの画像が無くなった。
Title Font
ナビゲーションバーのタイトルのフォント種類とサイズを指定する。
Title Color
ナビゲーションバーのタイトルのフォントカラーを指定する。
Title Shadow
ナビゲーションバーのタイトルの近くに表示する影の色を指定する。
影を配置する場所は「Default Position」と「Custom Offset」の2つから選択する。「Custom Offset」ではタイトルからの垂直方向と水平方向の距離を指定する。
下図はTitle Fontに「System Medium 30」、Title Colorに紫色、Title Shadowに緑色、Custom OffsetのHorizontalに「2」、Verticalに「2」を設定して実行した結果。