最后,在Beta 5中,我们可以通过编程方式弹出到父视图.然而,在我的应用程序中,有几个地方的视图有一个"保存"按钮,可以结束一个多步骤的过程并返回到开始.在UIKit中,我使用popToRootViewController(),但我一直无法找到在SwiftUI中执行同样操作的方法.

下面是我试图实现的模式的一个简单示例.有什么 idea 吗?

import SwiftUI

struct DetailViewB: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    var body: some View {
        VStack {
            Text("This is Detail View B.")

            Button(action: { self.presentationMode.value.dismiss() } )
            { Text("Pop to Detail View A.") }

            Button(action: { /* How to do equivalent to popToRootViewController() here?? */ } )
            { Text("Pop two levels to Master View.") }

        }
    }
}

struct DetailViewA: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    var body: some View {
        VStack {
            Text("This is Detail View A.")

            NavigationLink(destination: DetailViewB() )
            { Text("Push to Detail View B.") }

            Button(action: { self.presentationMode.value.dismiss() } )
            { Text("Pop one level to Master.") }
        }
    }
}

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 {
        NavigationView {
            MasterView()
        }
    }
}

推荐答案

NavigationLink上的视图修改器isDetailLink设置为false是使pop to root生效的关键.默认情况下,isDetailLinktrue,并且与包含的视图相适应.例如,在iPad上,分割视图是分开的,isDetailLink确保目标视图显示在右侧.因此,将isDetailLink设置为false意味着目标视图将始终被推到导航堆栈上;因此,总是可以弹出.

NavigationLink上将isDetailLink设置为false的同时,将isActive绑定传递给每个后续的目标视图.最后,当您想要弹出到根视图时,将该值设置为false,它将自动弹出所有内容:

import SwiftUI

struct ContentView: View {
    @State var isActive : Bool = false

    var body: some View {
        NavigationView {
            NavigationLink(
                destination: ContentView2(rootIsActive: self.$isActive),
                isActive: self.$isActive
            ) {
                Text("Hello, World!")
            }
            .isDetailLink(false)
            .navigationBarTitle("Root")
        }
    }
}

struct ContentView2: View {
    @Binding var rootIsActive : Bool

    var body: some View {
        NavigationLink(destination: ContentView3(shouldPopToRootView: self.$rootIsActive)) {
            Text("Hello, World #2!")
        }
        .isDetailLink(false)
        .navigationBarTitle("Two")
    }
}

struct ContentView3: View {
    @Binding var shouldPopToRootView : Bool

    var body: some View {
        VStack {
            Text("Hello, World #3!")
            Button (action: { self.shouldPopToRootView = false } ){
                Text("Pop to root")
            }
        }.navigationBarTitle("Three")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Screen capture

Swift相关问答推荐

出错-无法将季节类型的值转换为预期的参数类型';[水果]';

在不传递参数的情况下使用Init方法?

有条件地在同一视图上设置两个不同的过渡

OSX 中的 Popover 无法确定透明度

为什么Swift可以在没有足够信息的情况下推断类型?

macOS SwiftUI: 如何触发删除一个项目?

DispatchQueue.main.asyncAfter 等同于 Swift 中的 struct 化并发?

如何让默认函数参数引用另一个函数参数?

SwiftUI View .tint(_ Color) 方法不起作用

Swift:创建用于调用 C 函数的指针数组

单击按钮后的计时器发布者初始化计时器

任何使 ScrollView 像 List 一样执行更灵活的修饰符?

SwiftUI:从存储在 observableObject 中的数组中删除对象时查看崩溃

Swift 2 或 3 中的 Google Analytics 问题

根据禁用与否更改 SwiftUI 中按钮的 colored颜色

如何为多个类 Swift 进行扩展

Swift 3.0 的 stringByReplacingOccurencesOfString()

协议扩展中的where self是什么

自动布局:获取 UIImageView 高度以正确计算单元格高度

swift 中的@property/@synthesize 类似功能