Как запретить нажатому представлению временно отображать скрытую панель навигации?

Неожиданно выдвинутое представление SwiftUI временно отображает свое содержимое с пространством для скрытой панели навигации при переходе. Мгновение спустя он правильно отрисовывается. Как мне предотвратить такое поведение?

Для записи экрана в формате GIF щелкните изображение ниже.

ContentView.swift

import SwiftUI

struct ContentView: View {
    @State var goToNextView = false

    var body: some View {
        NavigationView { ZStack {
            /*@START_MENU_TOKEN@*/Color.yellow/*@END_MENU_TOKEN@*/.edgesIgnoringSafeArea(.all)
            NavigationLink(destination: SecondView(), isActive: $goToNextView) {Text("")}
                .navigationBarTitle("")
                .navigationBarHidden(true)
                .navigationBarBackButtonHidden(true)


            VStack {

                Button(action: {
                    print("Button clicked")
                    self.goToNextView = true
                }) { Text("Go to second view") }
                    .padding()
                Text("This is the first view.")

            }
        }
        .foregroundColor(Color.blue)

        }
    }
}

SecondView.swift

struct SecondView: View {

    var body: some View {

        ZStack {

            Color.purple
            .edgesIgnoringSafeArea(.all)

            .navigationBarBackButtonHidden(true)
            .navigationBarHidden(true)

            VStack { Text("Pushed view") }

        }
        .foregroundColor(Color.white)

    }
}

2 ответа

Решение

Я удалил это поведение, используя модификатор представления, на который повлиял этот ответ.

Встроенные комментарии объясняют внесенные мной изменения.

import SwiftUI

    struct ContentView: View {
        @State var goToNextView = false

        var body: some View {
            NavigationView { ZStack {
                /*@START_MENU_TOKEN@*/Color.yellow/*@END_MENU_TOKEN@*/.edgesIgnoringSafeArea(.all)
                NavigationLink(destination: SecondView(), isActive: $goToNextView) {Text("")}
                    // Removed all nav config code here
                VStack {
                    Button(action: {
                        print("Button clicked")
                        self.goToNextView = true
                    }) { Text("Go to second view") }
                        .padding()
                    Text("This is the first view.")
                }
            }
            // Added this to hide bar
            .hiddenNavigationBarStyle()
            .foregroundColor(Color.blue)

            }
        }
    }

    struct SecondView: View {
        var body: some View {
            ZStack {
                Color.purple
                .edgesIgnoringSafeArea(.all)
                    // Added this to hide bar
                    .hiddenNavigationBarStyle()
                VStack { Text("Pushed view") }
            }
            .foregroundColor(Color.white)
        }
    }

Это модификатор просмотра, взятый из предыдущего ответа:

struct HiddenNavigationBar: ViewModifier {
    func body(content: Content) -> some View {
        content
        .navigationBarTitle("", displayMode: .inline)
        .navigationBarHidden(true)
    }
}

extension View {
    func hiddenNavigationBarStyle() -> some View {
        ModifiedContent(content: self, modifier: HiddenNavigationBar())
    }
}

SwiftUI требует установить заголовок NavigationBar, даже если вы хотите скрыть панель навигации. В своем первом просмотре вы это сделали. Во втором - нет.

Добавление этого в ваш SecondView устраняет проблему:

.navigationBarTitle("")

И всего SecondView:

struct SecondView: View {

    var body: some View {

        ZStack {

            Color.purple
            .edgesIgnoringSafeArea(.all)

            .navigationBarTitle("")
            .navigationBarBackButtonHidden(true)
            .navigationBarHidden(true)

            VStack { Text("Pushed view") }

        }
        .foregroundColor(Color.white)

    }
}
Другие вопросы по тегам