Попрощайтесь с SwiftUI NavigationView с iOS 16
SwiftUI NavigationView с самого начала был ахиллесовой пятой фреймворка. Начиная с изначального запрета ленивых загрузок целевых представлений внутри NavigationLink (хотя это было решено позже) и заканчивая неспособностью программно перемещаться по глубоким ссылкам, структура навигации SwiftUI часто вынуждала нас возвращаться к использованию UINavigationController
.
К нашей передышке, в iOS 16 Apple предложила новую навигационную архитектуру, управляемую данными, вместо прежней структуры, управляемой представлениями.
Основные новые изменения API навигации включают в себя новый NavigationStack
, который позволяет отправлять и извлекать представления из стека, NavigationPath
для управления стеком маршрутизации и модификатор navigationDestination
для эффективной программной навигации по представлениям. С тем же обновлением они устарели NavigationView
.
Привет, NavigationStack
Интеграция NavigationStack в наш стек иерархии представлений очень проста:
NavigationStack {
NavigationLink {
Text("Destination Screen")
} label: {
Text("Goto Next Screen")
}
}
В некоторых тривиальных случаях мы можем напрямую провести рефакторинг нашего старого контейнера NavigationView
с новым контейнером NavigationStack
. Однако обратите внимание на новый синтаксис инициализации NavigationLink
.
API теперь содержит синтаксис value
-label
с меткой, содержащей представление контента для ссылки, и значением, содержащим построитель целевого представления.
Также стоит отметить, что старые методы инициализации NavigationLink, такие как NavigationLink(isActive:destination:label:)
, устарели.
Точно так же NavigationLink(destination:tag:selection:)
также устарел в iOS 16, что означает, что рефакторинг программной навигации на основе NavigationLink потребует совершенно другого кода.
Программная навигация с использованием модификатора 'navigationDestination"
В предыдущем разделе мы увидели, как установить целевое представление NavigationLink
в самом коде инициализации. Однако вы, возможно, помните ту боль, которую доставляли нам isActive
логические флаги при создании сложных навигационных структур до iOS 16.
К счастью, начиная с iOS 16 мы можем установить целевой вид внутри модификатора .navigationDestination
. navigationDestination
дает нам возможность программно направлять на разные экраны в зависимости от типа. Вы также можете добавить несколько модификаторов navigationDestination
для разных типов представления.
В приведенном ниже примере мы создали навигационное приложение SwiftUI, которое создает такое же представление списка на экране назначения:
Маршрутизация NavigationLink с использованием NavigationPath
Раньше для маршрутизации NavigationLink у нас было tags
.
В iOS 16 у нас появился новый мощный NavigationPath
, который может хранить стертые данные типа, относящиеся к представлениям, отображаемым в NavigationStack
.
Сила NavigationPath
заключается в его способности легко выталкивать из стека представления, принадлежащие разным типам данных.
Рассмотрим приведенное ниже приложение, в котором мы подключили NavigationPath
к нашему NavigationStack
:
Мы установили наш NavigationPath
внутри класса ObservableObject
и установили его в EnvironmentObject
, чтобы передать его дочерним представлениям. Хотя вы также можете использовать @Binding
для того же.
Обратите внимание на измененный файл NavigationStack(path:)
init.
Вот код для RowListsView
:
Мы немного изменили приведенное выше представление SwiftUI — чтобы включить настраиваемые кнопки «Назад», которые программно изменят NavigationPath
, что, в свою очередь, изменит представление NavigationStack
:
Мы увидели, как легко вернуться к корню, вызвав следующий фрагмент кода:
router.path = .init()
Вы можете вернуться к любому экрану, нажав и удерживая кнопку «Назад», которая показывает раскрывающийся список с предыдущими заголовками экрана. Теперь заголовки будут отображать back
по умолчанию, но вы можете настроить их, установив модификатор .navigationTitle(string:)
.
На этом вводная статья о новом навигационном стеке SwiftUI завершена, но вы можете сделать гораздо больше, используя новые шаблоны, например, обрабатывать глубокие ссылки и многое другое.
Кроме того, для поддержки новых API-интерфейсов навигации в предыдущих версиях iOS есть потрясающая библиотека с открытым исходным кодом.
Это все на данный момент. Вот суть всего фрагмента кода SwiftUI.