1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【対話形式で学ぶ】iOS26でタイトル(navigationItem.titleView)が消えた!? Auto Layoutをやめたら直った話

Posted at

👩‍🏫 登場人物

  • 先生:ちょっとマニアックなプログラマー先生
  • さくら:高校生でSwiftを勉強中
  • ケン:クラスの技術マニア。フレームワークの裏側まで気になるタイプ

🎬 Scene 1:iOS 26アップデート後、タイトルが消えた!?

さくら「先生〜!iOS 26にしたら、ナビゲーションバーのタイトルが消えちゃいました!😭」

先生「おっ、それは“タイトル消失バグ”だね。最近よくあるやつだよ。」

ケン「タイトルって、普通 navigationItem.titleView にビューを入れてるやつですよね?」

先生「そう。でも iOS 26 から内部構造が変わって、Auto Layoutで配置するとズレたり消えたりするようになったんだ。」


🧠 Scene 2:Auto Layoutが悪さをしていた?

さくら「えっ、Auto Layoutって便利じゃないんですか?」

先生「もちろん便利。でも、ナビゲーションバーの中だけは特殊なんだ。
Apple が内部で自動的に制約を貼り直したりするから、開発者が指定した制約とぶつかってレイアウトが壊れることがある。」

ケン「なるほど…じゃあ、Auto Layoutをやめれば直るんですか?」

先生「そう。昔ながらのやり方に戻すんだ。つまり autoresizing mask + 手動 frame 調整!」


🛠 Scene 3:UIKitでの修正方法

💡基本方針

  • Auto Layout(制約)を使わない
  • autoresizing maskでサイズ変化に追従
  • viewDidLayoutSubviews() で frame を手動調整

✅ コード例(UIKit)

import UIKit

final class DemoViewController: UIViewController {
    private let titleContainer = UIView()
    private let titleLabel = UILabel()

    override func viewDidLoad() {
        super.viewDidLoad()

        // タイトル用ラベル
        titleLabel.text = "カスタムタイトル"
        titleLabel.font = .boldSystemFont(ofSize: 17)
        titleLabel.textAlignment = .center

        // Auto Layoutを使わず、autoresizingで対応
        titleContainer.translatesAutoresizingMaskIntoConstraints = true
        titleContainer.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        titleLabel.translatesAutoresizingMaskIntoConstraints = true
        titleLabel.autoresizingMask = [.flexibleWidth, .flexibleHeight]

        // 階層に追加
        titleContainer.addSubview(titleLabel)
        navigationItem.titleView = titleContainer

        // Large Titleを無効化(レイアウト揺れ防止)
        navigationItem.largeTitleDisplayMode = .never
        navigationController?.navigationBar.prefersLargeTitles = false
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        // ナビゲーションバーのサイズに合わせて更新
        if let bar = navigationController?.navigationBar {
            titleContainer.frame = bar.bounds
            titleLabel.frame = titleContainer.bounds
        }
    }
}

🔍 ここがポイント!

項目 内容
Auto Layout無効化 translatesAutoresizingMaskIntoConstraints = true
サイズ調整 autoresizingMask = [.flexibleWidth, .flexibleHeight]
手動更新 viewDidLayoutSubviews()frameを再設定
Large Title対策 largeTitleDisplayMode = .never 推奨

🪄 Scene 4:SwiftUIでも再現可能!

さくら「私はSwiftUI派なんですけど、これできるんですか?」

先生「もちろん!SwiftUIのツールバーは内部的にナビゲーションバーを使ってる。
だから UIKit のラベルを SwiftUI でラップすれば同じことができるよ。」

✅ コード例(SwiftUI)

import SwiftUI

// UIKitのUILabelをSwiftUIで使えるようにする
struct TitleHost: UIViewRepresentable {
    func makeUIView(context: Context) -> UILabel {
        let label = UILabel()
        label.text = "カスタムタイトル"
        label.font = .boldSystemFont(ofSize: 17)
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = true
        label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        return label
    }
    func updateUIView(_ uiView: UILabel, context: Context) {}
}

struct ContentView: View {
    var body: some View {
        Text("本文")
            .toolbar {
                ToolbarItem(placement: .principal) {
                    TitleHost()
                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                }
            }
            .navigationBarTitleDisplayMode(.inline)
    }
}

🧩 Scene 5:なぜこれで直るの?

ケン「Auto Layoutをやめるだけで、なんで直るんですか?」

先生「iOS 26ではナビゲーションバーの内部構造が変更されて、Auto Layoutの制約が
Appleの内部制約と衝突するようになったんだ。
その結果、タイトルのビューが0×0サイズになって“消えて見える”状態になってたんだよ。」

さくら「そんな落とし穴が…!じゃあ、autoresizingを使うと?」

先生「autoresizingは単純で、親ビューのサイズに合わせて伸び縮みするだけ
つまりAppleの内部制約に左右されにくい。
Auto Layoutより“おおらか”な仕組みだから、バーの変更にも自然に追従できるんだ。」


📘 Scene 6:今日のまとめノート

💡ポイント 内容
問題 iOS 26でnavigationItem.titleViewが非表示になる
原因 Auto Layoutの制約がナビバーの内部変更と競合
対策 Auto Layoutを使わず、autoresizing mask+手動frame調整で安定化
SwiftUI対応 UIViewRepresentableでUILabelをラップして同様の処理を行う
注意点 viewDidLayoutSubviews()で毎回frameを更新してサイズ変化に対応

👋 Scene 7:エンディング

先生「こうしてフレームワークの“裏側”を知ると、
単に“動く”だけじゃなく、“なぜ動くか”も理解できるようになるんだ。」

さくら「今日の授業で、“Auto Layoutを信じすぎない勇気”を学びました!」

ケン「次はタイトルバーにロゴとか検索バーも置いてみたいです!」

先生「いいね、それが次の課題だね!」


🧭 構造イメージ

UINavigationBar
├── UINavigationItem
│ └── titleView (UIView)
│ └── UILabel(タイトル表示)
└── viewDidLayoutSubviews()でframe更新

🔗 参考リンク


🏁 この記事のテーマ

「Auto Layoutは万能じゃない。
時には“昔ながらのゴムひも(autoresizing)”が一番強い。」

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?