首页 > 解决方案 > 从子视图 SwiftUI 中删除 UI 元素

问题描述

我正在尝试创建一个 SwiftUI 视图,该视图将充当我正在设计的应用程序的一种主页。作为其中的一部分,我想在主页顶部包含一个突出的搜索栏。但是,也许我对 SwiftUI 中的工作方式NavigationViewTabBar工作方式有点困惑,因为当我导航到我想要的子页面时,搜索栏并没有消失。这是一个 gif,展示了我在说什么:

一旦我导航到特定的测试帖子,我希望搜索栏消失,但它仍然存在于页面顶部,而 NavigationLink 中的视图发生变化:

VStack(spacing: 0) {
    HStack(spacing: 0) {
        Image(systemName: "heart.fill")
            .padding([.leading, .bottom, .trailing], 2.0)
            .frame(width: 99, height: 99, alignment: .topLeading)
            .aspectRatio(contentMode: .fill)
        SearchBar(text: $searchTerm)
            .edgesIgnoringSafeArea(.all)
    }

    // I only want all of this displayed within the parent view, the home page.

    NavigationView {
        List(categories.keys.sorted(), id: \String.self) {
            // ... create the view
        }
        .navigationBarTitle(Text("SwiftUI Test"))
    }
    .onAppear{ // do stuff }
}

下面是一个在页面底部创建工具栏的代码示例,将这个“主页”(名为 FeedView())和另一个暂时不相关的页面分开。

struct AppView: View {
    var body: some View {
        TabView {
            FeedView()
                .tabItem {
                    Image(systemName: "house.fill")
                    Text("Feed")
                }
            // other pages in the navbar
        }.navigationBarBackButtonHidden(true)
    }
}

我的问题是什么?如何从所有非父页面中删除搜索栏?


编辑

在实施 Asperi 的更改后,我遇到了一个新问题。为了在两个类之间传递它们的变量,我必须创建一些新变量@State和变量,并且响应时间有点慢,并且大约一半的时间正确传递了更新。看一看:@BindingshowHeader

破碎的

以及相关代码更改:(父视图)

@State private var showHeader = true

var body: some View {
    VStack(spacing: 0) {
        if showHeader {
            HStack(spacing: 0) {
                // header
            }
        }

        NavigationView {
            List(categories.keys.sorted(), id: \String.self) {
                key in CategoryRow(nameOfCategory: "\(key)".uppercased(), posts: self.posts[key]!, showHeader: self.$showHeader)
            }
        }  

(子视图;一个 CategoryRow 元素):

@Binding var showHeader: Bool

// ...

NavigationLink(destination: ExpandMediaView(post: post)
    .onAppear { self.showHeader = false }
    .onDisappear { self.showHeader = true }
)

代码有时只命中.onDisappearNavigationLink 的一部分。为什么?

标签: swiftswiftui

解决方案


您的搜索栏不在导航视图中,这就是导航后它仍然可见的原因,因为您的导航是导航视图中执行的,而不是全屏。

因此,实现您的目标的方法可能如下(示意性地,提供的代码不可测试)

@State private var showHeader = true // << add conditional state for header
...
VStack(spacing: 0) {
    if showHeader { // << present header conditionally
      HStack(spacing: 0) {
          Image(systemName: "heart.fill")
              .padding([.leading, .bottom, .trailing], 2.0)
              .frame(width: 99, height: 99, alignment: .topLeading)
              .aspectRatio(contentMode: .fill)
          SearchBar(text: $searchTerm)
              .edgesIgnoringSafeArea(.all)
      }
    }
    // I only want all of this displayed within the parent view, the home page.

    NavigationView {
        List(categories.keys.sorted(), id: \String.self) {
            // ... create the view
            NavigationLink(destination: 
               YourDestinationView()
                  .onAppear { self.showHeader = false } // << hide header
                  .onDisappear { self.showHeader = true } // << show header
            ) { 
              // ... label here
            }
        }
        .navigationBarTitle(Text("SwiftUI Test"))
    }
    .onAppear{ // do stuff }
}

推荐阅读