Как скрыть Navigation Bar на первом экране в Swift: полный гайд

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: почему скрытие Navigation Bar — это боль для новичка?

Вы когда-нибудь сталкивались с ситуацией: создаёте приложение, первый экран должен выглядеть как полноэкранный лендинг, без серой полоски сверху, а на втором экране Navigation Bar уже нужен для навигации? Казалось бы, логично просто написать navigationController?.isNavigationBarHidden = true во viewDidLoad. Но тут начинается магия: Navigation Bar может «вылезти» обратно при возврате с другого экрана, анимация ломается, или он вообще не скрывается.

Это один из самых популярных вопросов на Stack Overflow (тема «How to hide a navigation bar from first ViewController in Swift?» набрала тысячи просмотров). В этом туториале мы разберём не только базовое решение, но и тонкие моменты: как сделать это красиво, без багов с анимацией, и как адаптировать под современные iOS-стандарты. Если вы ищете надёжный способ скрыть navigation bar на первом экране в Swift — вы по адресу.

Проблема: что происходит «под капотом»?

Когда вы используете UINavigationController, он управляет Navigation Bar для всех дочерних контроллеров. Если вы просто скрываете его в viewDidLoad первого ViewController, при переходе на второй экран и возврате назад свойство может сброситься. Почему?

  • viewDidLoad вызывается один раз — при повторном показе экрана код не выполнится.
  • UINavigationController синхронизирует bar на основе последнего контроллера в стеке.
  • Анимация перехода может «зажевать» состояние, если не задать animated параметры.

Но не переживайте — решение элегантное и простое. Давайте напишем код.

Базовое решение: скрываем Navigation Bar в первом ViewController

Самый прямой способ — переопределить метод viewWillAppear. Почему именно здесь? Потому что этот метод вызывается каждый раз перед появлением экрана, в отличие от viewDidLoad. Таким образом, даже после возврата с другого экрана Navigation Bar снова скроется.

Шаг 1: Создаём первый ViewController

Допустим, у вас есть FirstViewController, который является корневым в UINavigationController.

import UIKit

class FirstViewController: UIViewController {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // Скрываем Navigation Bar без анимации
        navigationController?.setNavigationBarHidden(true, animated: animated)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // Возвращаем Navigation Bar при уходе с экрана
        navigationController?.setNavigationBarHidden(false, animated: animated)
    }
}

Обратите внимание: мы используем setNavigationBarHidden(_:animated:) с параметром animated. Если передать true, Navigation Bar будет скрываться/появляться с анимацией, синхронизированной с переходом. Это выглядит профессионально.

Шаг 2: Настраиваем второй экран

На втором экране (SecondViewController) Navigation Bar будет отображаться по умолчанию. Ничего дополнительно писать не нужно — он появится автоматически при переходе.

Шаг 3: Проверяем в Interface Builder или коде

Убедитесь, что ваш UINavigationController настроен правильно. Если вы используете Storyboard, проверьте, что первый экран — это FirstViewController. Если в коде:

let navController = UINavigationController(rootViewController: FirstViewController())

Готово! Запустите приложение — первый экран будет без Navigation Bar, второй — с ним.

Продвинутые техники: анимация и SwiftUI

Базовое решение работает, но в реальных проектах часто нужны нюансы. Рассмотрим несколько сценариев.

Сценарий 1: Плавное скрытие с анимацией

Если вы хотите, чтобы Navigation Bar исчезал плавно при скролле или по тапу, можно использовать UIView.animate:

func hideNavigationBarAnimated() {
    UIView.animate(withDuration: 0.3) {
        self.navigationController?.navigationBar.alpha = 0
    }
    navigationController?.navigationBar.isHidden = true // На всякий случай
}

Но будьте осторожны: изменение alpha может привести к артефактам. Лучше использовать встроенный метод setNavigationBarHidden с анимацией.

Сценарий 2: Использование UINavigationControllerDelegate

Если у вас сложная иерархия и вы хотите управлять видимостью Navigation Bar централизованно, реализуйте протокол UINavigationControllerDelegate:

class CustomNavigationController: UINavigationController, UINavigationControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }

    func navigationController(_ navigationController: UINavigationController,
                              willShow viewController: UIViewController,
                              animated: Bool) {
        // Скрываем Navigation Bar только для первого экрана
        let hideBar = viewController is FirstViewController
        navigationController.setNavigationBarHidden(hideBar, animated: animated)
    }
}

Этот подход особенно полезен, если у вас много экранов и вы не хотите писать код в каждом контроллере.

Сценарий 3: SwiftUI и NavigationView

Если вы пишете на SwiftUI, задача решается ещё проще. Используйте модификатор .navigationBarHidden:

struct FirstView: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: SecondView()) {
                    Text("Перейти")
                }
            }
            .navigationBarHidden(true)
        }
    }
}

struct SecondView: View {
    var body: some View {
        Text("Второй экран")
            .navigationBarHidden(false) // Показываем Navigation Bar
    }
}

В SwiftUI Navigation Bar автоматически управляется через модификаторы, но будьте внимательны: если вы используете .navigationBarHidden(true) на первом экране, на втором нужно явно указать false, иначе бар может не появиться.

Частые ошибки и как их избежать

Даже опытные разработчики иногда наступают на эти грабли. Вот топ-3 ошибки при попытке скрыть navigation bar в Swift:

  • Забыли про viewWillDisappear — если вы скрыли бар на первом экране, но не вернули его при уходе, второй экран тоже будет без бара. Всегда парно используйте viewWillAppear и viewWillDisappear.
  • Использование isNavigationBarHidden = true без анимации — при переходе назад может возникнуть «моргание» бара. Всегда используйте setNavigationBarHidden(_:animated:).
  • Попытка скрыть бар в viewDidLoad — это сработает только при первом появлении. При возврате с другого экрана бар появится снова.

Почему это важно для UX?

Скрытие Navigation Bar на первом экране

Блоги

Рекомендаций по книгам