如何使用主视图/详细视图截取/处理后退按钮

时间:2020-08-27 13:18:28

标签: navigation swiftui

这个问题最初是关于在重新显示原始主视图时如何清除或重绘详细视图的建议的请求,但是在创建示例时,我发现没有任何@State变量,该原始视图正在部队刷新得远远超出了必要,并且想了解为什么以及如何做我需要的事情。

import SwiftUI

var ctr = 0


struct ContentView: View
{
    var body: some View
    {
        NavigationView
        {
            NavigationLink(destination: SecondView())
            {
                Text("Left Pane")
                .padding()
                    .onAppear()
                    {
                        ctr = ctr+1
                        print("Appear \(ctr)")
                    }
            }.isDetailLink(false)
        }
    }
}

struct SecondView: View
{
    var body: some View
    {
        NavigationLink(destination: ThirdView())
        {
            Text("Selector View")
                .padding()
                .onAppear()
                {
                    print("Selector Appears")
                }
        }
    }
}

struct ThirdView: View
{
    var body: some View
    {
        Text("Third View - Detail")
    }
}

依次单击链接时,控制台显示以下内容,然后后退按钮最终显示原始的主视图。我的目标是在到达那里时将详细信息视图更改为空白,但是我看不到做到这一点的方法,也看不到每个视图为什么会有如此多的刷新。

Appear 1
Appear 2
Appear 3
Appear 4
Appear 5
Selector Appears
Selector Appears
Selector Appears
Selector Appears
Selector Appears
Appear 6
Appear 7
Appear 8
Appear 9
Appear 10

换一种说法,我最初的问题是如何拦截或处理后退按钮?

1 个答案:

答案 0 :(得分:0)

这里是一个可能方法的演示-想法是明确重置详细信息视图,因为在SwiftUI中,我们不能仅将某些视图设置为blank-我们需要用某些内容替换它。

在Xcode 12 / iOS 14上进行了测试(因此可能需要一些适应SwiftUI 1.0的内容)

demo

class DetailsState: ObservableObject { // view model to manage details
    @Published var reset = false
}

struct ContentView: View {
    @StateObject var state = DetailsState()

    var body: some View
    {
        NavigationView
        {
            NavigationLink(destination: SecondView()
                .onAppear()
                {
                    self.state.reset = true        // << should be here !!
                }
            )
            {
                Text("Left Pane")
                .padding()
            }.isDetailLink(false)
        }
        .environmentObject(state)
    }
}

struct SecondView: View
{
    @EnvironmentObject var state: DetailsState

    @State private var showDetails = false
    var body: some View
    {
        Button("Selector View") {
            state.reset = false      // << drop on activation
            showDetails = true       // << activate details
        }
        .padding()
        .background(
            NavigationLink(destination: ThirdView(), isActive: $showDetails)
                { EmptyView() }
        )
    }
}

struct ThirdView: View     // managed container for selected views
{
    @EnvironmentObject var state: DetailsState

    var body: some View
    {
        if !state.reset {    // << show when allowed
            Text("Third View - Detail")  // << selected view here 
        }
    }
}