SwiftUI: как переключиться на новый стек навигации с помощью NavigationViews
В настоящее время я использую SwiftUI Beta 5. У меня есть рабочий процесс, который включает навигацию по серии представлений. Последнее представление включает в себя операцию, которая заполняет загрузку данных в приложение и завершает этот конкретный рабочий процесс.
После того, как данные были загружены, пользователь должен иметь возможность начать новый рабочий процесс (ы). Я хотел бы "забыть" о старом NavigationView, поскольку нет смысла возвращаться назад через стек навигации после завершения рабочего процесса. Вместо этого я хотел бы перейти к представлению "запуска", которое фактически становится корнем нового представления навигации.
Как одно представление в стеке навигации можно использовать для перехода к другому представлению с другим NavigationView (и, следовательно, становится корнем для нового стека навигации) с использованием SwiftUI NavigagationViews?
2 ответа
Во-первых, извините, я хотел оставить простой комментарий, но недостаточно репутации:(
Я только что обновил свой способ, чтобы вернуться к руту вы на stackru.com/a/57513566/7786555
Вы на самом деле дали мне идею с вашим комментарием для нового способа вернуться к корню. Имея новый корневой вид. Если вы принудительно обновите представление структуры, управляющее корневым представлением, оно автоматически сделает то, что вы хотите. Здесь только возвращается к корню (без анимации). Вы можете адаптировать пример для изменения корневого представления (вместо использования того же самого) в соответствии с вашими потребностями.
struct DetailViewB: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@State var fullDissmiss:Bool = false
var body: some View {
SGNavigationChildsView(fullDissmiss: self.fullDissmiss){
VStack {
Text("This is Detail View B.")
Button(action: { self.presentationMode.wrappedValue.dismiss() } )
{ Text("Pop to Detail View A.") }
Button(action: {
self.fullDissmiss = true
} )
{ Text("Pop two levels to Master View with SGGoToRoot.") }
}
}
}
}
struct DetailViewA: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@State var fullDissmiss:Bool = false
var body: some View {
SGNavigationChildsView(fullDissmiss: self.fullDissmiss){
VStack {
Text("This is Detail View A.")
NavigationLink(destination: DetailViewB() )
{ Text("Push to Detail View B.") }
Button(action: { self.presentationMode.wrappedValue.dismiss() } )
{ Text("Pop one level to Master.") }
Button(action: { self.fullDissmiss = true } )
{ Text("Pop one level to Master with SGGoToRoot.") }
}
}
}
}
struct MasterView: View {
var body: some View {
VStack {
Text("This is Master View.")
NavigationLink(destination: DetailViewA() )
{ Text("Push to Detail View A.") }
}
}
}
struct ContentView: View {
var body: some View {
SGRootNavigationView{
MasterView()
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
struct SGRootNavigationView<Content>: View where Content: View {
let cancellable = NotificationCenter.default.publisher(for: Notification.Name("SGGoToRoot"), object: nil)
let content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
@State var goToRoot:Bool = false
var body: some View {
return
Group{
if goToRoot == false{
NavigationView {
content()
}
}else{
NavigationView {
content()
}
}
}.onReceive(cancellable, perform: {_ in
DispatchQueue.main.async {
self.goToRoot.toggle()
}
})
}
}
struct SGNavigationChildsView<Content>: View where Content: View {
let notification = Notification(name: Notification.Name("SGGoToRoot"))
var fullDissmiss:Bool{
get{ return false }
set{ if newValue {self.goToRoot()} }
}
let content: () -> Content
init(fullDissmiss:Bool, @ViewBuilder content: @escaping () -> Content) {
self.content = content
self.fullDissmiss = fullDissmiss
}
var body: some View {
return Group{
content()
}
}
func goToRoot(){
NotificationCenter.default.post(self.notification)
}
}
Вот как мы решили этот вопрос: у нас было представление main/root/launch, из которого пользователь мог нажать кнопку, чтобы запустить какой-либо бизнес-процесс. Это откроет лист, который будет отображать модальное всплывающее окно. (Ширина и высота листов могут быть настроены так, чтобы они занимали большую часть/весь экран.)
Лист будет иметь NavigationView. Это позволит пользователю пройти серию представлений как часть рабочего процесса. Флаг «представленный» передается как привязка из основного представления к каждому представлению с навигацией.
Когда пользователь достигает последнего представления и нажимает кнопку «Отправить/Готово/Готово», чтобы завершить этот конкретный рабочий процесс, для «представленной» привязки может быть установлено значение false, что закрывает модальное всплывающее окно и возвращает пользователя обратно в основное представление. .