Какие способы навигации доступны в SwiftUI?

Ответ

SwiftUI предлагает декларативные API для различных сценариев навигации.

Основные компоненты:

  1. NavigationStack (iOS 16+) — современная замена NavigationView. Поддерживает глубокую навигацию и типобезопасную передачу данных через navigationDestination.

    struct ContentView: View {
        var body: some View {
            NavigationStack {
                List(1..<5) { number in
                    NavigationLink("Item (number)", value: number)
                }
                .navigationDestination(for: Int.self) { value in
                    DetailView(itemId: value) // Переход по значению
                }
            }
        }
    }
  2. NavigationView (устарел) — основа навигации до iOS 16. Использует NavigationLink с явным указанием destination.

  3. Модальные представления:

    • .sheet — стандартное модальное окно.
    • .fullScreenCover — полноэкранное модальное окно.
      @State private var showSettings = false
      Button("Show Settings") { showSettings.toggle() }
      .sheet(isPresented: $showSettings) {
          SettingsView()
      }
  4. TabView — для таб-бара.

    TabView {
        HomeView()
            .tabItem { Label("Home", systemImage: "house") }
        ProfileView()
            .tabItem { Label("Profile", systemImage: "person") }
    }
  5. Программная навигация — через NavigationPath в NavigationStack или состояние, управляемое @StateObject/@ObservableObject (координаторный паттерн).

Рекомендация: Для новых проектов используйте NavigationStack, так как он предоставляет больше контроля над стеком навигации и является будущим фреймворка.

Ответ 18+ 🔞

А, навигация в SwiftUI, говоришь? Ну, это ж классика, блядь! Ситуация, когда фреймворк такой: "Вот тебе, разработчик, пять разных способов сделать одно и то же, и один из них уже устарел, пока ты моргнул, ёпта!"

Смотри, тут главное не запутаться, а то можно такую навигационную хуйню выстроить, что сам черт ногу сломит.

Основные кирпичи, из которых тут всё лепится:

  1. NavigationStack (только с iOS 16+) — это новый царь и бог, замена тому старому деду. Он не просто экраны пушит, он это делает с типобезопасностью, блядь! То есть ты не просто "перейди куда-то", а "перейди к экрану для числа 42". Красота!

    struct ContentView: View {
        var body: some View {
            NavigationStack {
                List(1..<5) { number in
                    NavigationLink("Item (number)", value: number) // Говорим: "Вот значение"
                }
                .navigationDestination(for: Int.self) { value in // А здесь: "А вот если значение — число, вот тебе экран для него!"
                    DetailView(itemId: value)
                }
            }
        }
    }

    Чисто, элегантно, мозг не ебёт. В рот меня чих-пых, как же раньше без этого жили.

  2. NavigationView (устарел, блядь!) — это как старый дедовский мотоцикл "Иж". Ехал, гремел, но вроде работал. Сейчас на нём уже стыдно ездить в новые проекты, все пальцем показывать будут. Там надо было каждый NavigationLink вручную привязывать к конкретному экрану-пункту назначения. Скучно.

  3. Модалки, они же "всплывашки". Тут два главных героя:

    • .sheet — классическая штука, всплывает снизу, как шторка. Для настроек, форм — идеально.
    • .fullScreenCover — овердохуищный, на весь экран. Когда нужно, чтобы юзер отвлёкся и ни хуя больше не видел.
      @State private var showSettings = false
      Button("Тыкни меня") { showSettings.toggle() } // Тыкнул — состояние поменялось
      .sheet(isPresented: $showSettings) { // Состояние изменилось — блядь, выезжай, модалка!
          SettingsView()
      }

      Всё через биндинги, просто пиздец.

  4. TabView — для тех, кто любит понизу тыкать. Табы, вкладки, как в старых добрых временах. Никакой магии, всё предсказуемо.

    TabView {
        HomeView()
            .tabItem { Label("Домой", systemImage: "house") }
        ProfileView()
            .tabItem { Label("Я", systemImage: "person.circle.fill") }
    }
  5. Программная навигация, или "Я сам всё решу". Вот тут начинается настоящий цирк. Можно использовать NavigationPath внутри NavigationStack и толкать туда значения, как в стек. А можно замутить какой-нибудь координатор на @StateObject, который будет всем этим бардаком рулить. Мощно, гибко, но если накосячить — отладка будет та ещё пиздопроебибна.

Итог, блядь: Если делаешь что-то новое и таргет на iOS 16+, даже не думай — бери NavigationStack и не парься. Он и логичнее, и мощнее. А всё остальное — либо для поддержки старья, либо для особых извращенных случаев. Не усложняй себе жизнь, чувак!