【Swift】NavigationBarのタイトルをLargeTitleを使用せずに左寄せにする方法

【Swift】NavigationBarのタイトルをLargeTitleを使用せずに左寄せにする方法

Clock Icon2022.11.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

NavigationBarのタイトルを左寄せにしたい時がついにやってきたのでその方法を調べました。

環境

  • Xcode 14.1

Storyboard

今回はこのようにNavigationControllerをEmbedしたViewControllerで説明していきます。

NavigationBarのタイトルを左寄せにする

LargeTitleを使用する

左寄せにするだけなら、navigationBar.prefersLargeTitlesを有効にし、navigationItem.largeTitleDisplayModeでlargeTitleが表示されるように設定しておけば、簡単に表現出来ます。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        setupNavigationBarTitle()
    }

    private func setupNavigationBarTitle() {
        title = "お気に入りリスト"
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.largeTitleDisplayMode = .always
    }
}

ただ、largeTitleだとNavigationBarの縦幅が広くなっている為、アプリによってはもう少し狭くしたいという要望が出てくるかもしれません。

largeTitleのフォントを小さくする

largeTitleのフォントを小さくする方法を試してみました。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        setupNavigationBarTitle()
    }

    private func setupNavigationBarTitle() {
        title = "お気に入りリスト"
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.largeTitleDisplayMode = .always

        // LargeTitleのフォントを小さくする
        setAppearanceForLargeTitleText()
    }

    private func setAppearanceForLargeTitleText() {
        let appearance = UINavigationBarAppearance()
        appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.label,
                                               .font: UIFont.systemFont(ofSize: 12, weight: .bold)]
        appearance.backgroundColor = .systemBackground
        navigationItem.standardAppearance = appearance
        navigationItem.scrollEdgeAppearance = appearance
    }
}

largeTitleのフォントを小さくしても、フォントは小さくなるがNavigationBarの縦幅は小さくなりませんでした。

LargeTitleを使用せず、タイトルを左寄せにする

navigationItem.titleViewにテキストを左寄せしたUILabelを設定する方法です。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        setupNavigationBarTitle()
    }

    private func setupNavigationBarTitle() {
        title = "お気に入りリスト"

        // navigationBarのタイトルを左寄せにする
        setNavigationBarLeftTitle("お気に入りリスト")
    }

    func setNavigationBarLeftTitle(_ title: String) {

        // titleViewとして設定したいUILabelのframeを設定する
        let titleLabel = UILabel(frame: CGRect(x: 4, y: 0, width: view.frame.width, height: 28))

        // 左寄せのタイトルを設定する
        titleLabel.text = title
        titleLabel.textAlignment = .left
        titleLabel.font = .systemFont(ofSize: 12, weight: .bold)
        titleLabel.textColor = .black

        // 生成したUILabelをtitleViewに設定する
        navigationItem.titleView = titleLabel
    }
}

navigationItem.titleViewにカスタムViewを設定することで独自のタイトルを表現することが出来ます。

このプロパティ値がnil、レシーバーがトップアイテムの場合、ナビゲーションアイテムのタイトルがナビゲーションバーの中央に表示されます。このプロパティをカスタムタイトルに設定すると、タイトルの代わりに表示されます。

引用: titleView

Extensionを作成する

汎用的に使用する為のExtensionを作成しました。

extension UIViewController {

    func setNavigationBarLeftTitle(_ title: String, textColor: UIColor = .label, fontSize: CGFloat, weight: UIFont.Weight = .bold) {

        let titleLabel = UILabel(frame: CGRect(x: 4, y: 0, width: view.frame.width, height: 28))
        // 左寄せのタイトルを設定する
        titleLabel.text = title
        titleLabel.textAlignment = .left
        titleLabel.font = .systemFont(ofSize: fontSize, weight: weight)
        titleLabel.textColor = textColor
        // 生成したUILabelをtitleViewに設定する
        navigationItem.titleView = titleLabel
    }
}

フォントのサイズやウェイト、テキストのカラー、UILabel自身のCGPoint等は好みの値を設定していただければと思います。

使用例

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        setNavigationBarLeftTitle("お気に入りリスト", fontSize: 18)
    }
}

おわりに

無事に左寄せのNavigationBarのタイトルを表現することが出来ました。基本的には標準のNavigationBarを使うと思いますが、もし左寄せがしたいと思った誰かの救いにこの記事がなればと思います。

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.