Как скрыть TabView при открытии нового представления с помощью NavigationLink?

Предполагая, что у нас есть представление SwiftUI, содержащее

struct ContentView: View {
    var body: some View {
        TabView {
            FirstView().tabItem {
                // tabItem image and text
            }
            SecondView().tabItem {
                // tabItem image and text
            }
        }
    }
}

Теперь скажем FirstView содержит NavigationView с прокручиваемым контентом с помощью NavigationLinkдля каждого элемента. Как сделать так, чтобы когда NavigationLink целевой объект запускается (т.е. открывается дочернее представление), который занимает всю страницу (в полноэкранном режиме) и, таким образом, скрывает TabView?

В идеале я хотел бы поддерживать iOS 13+.

Я пытался следовать указаниям в разделе " Взлом со Swift", но безуспешно.

Я также последовал совету в SwiftUI Hide TabView bar внутри представлений NavigationLink, но обнаружил, что лучшее решение не так производительно, поэтому я надеюсь найти решение без задержки появления.

2 ответа

Приложите содержимое вашего tabitemвнутри условия if, которое проверяет общее состояние:

      struct ContentView: View {

    @StateObject private var state = State()

    var body: some View {
        TabView {
            FirstView().tabItem {
                if !state.hideTabView {
                    // tabItem image and text
                }
            }
            SecondView().tabItem {
                if !state.hideTabView {
                    // tabItem image and text
                }
            }
        }
        .environmentObject(state)
    }
}

Где Stateявляется ObservableObjectкак таковой:

      class State: ObservableObject {
    @Published hideTabView: Bool = false
}

Затем вы можете использовать onAppearв представлении, которое связано с через NavigationLink(например, внутри FirstView):

      struct FirstView: View {
    
    @EnvironmentObject private var state: State
    var body: some View {
        VStack {
            // ... some content
        }
        .onAppear(perform: { state.hideTabView = true })
        .onDisappear(perform: { state.hideTabView = false })
    }
}

Существует небольшая задержка при повторном появлении TabView, когда вы нажимаете «< Назад», если это вас действительно беспокоит, вы можете создать пользовательскую кнопку «Назад» и переместить ее. state.hideTabView = falseк событию нажатия этой кнопки.

Это один из подходов, который я могу придумать :) Кроме того, вы можете найти эту ветку полезной.

Одним из решений является удаление ваших дочерних представлений (FirstView и SecondView) и размещение одного NavigationViewза пределами вашего .

      NavigationView {
    TabView {
        //...
    }
}

Это правильно ставит ваш TabViewв стеке навигации, а не в родительском стеке навигации. Это может привести к нежелательным результатам, включая изменение заголовка navigationBar и пользовательского интерфейса, поскольку вы перемещаете корень стека навигации вверх по течению, однако это сработало для моего варианта использования.

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