从子视图SwiftUI移除UI元素

时间:2020-02-04 23:14:07

标签: swift swiftui

我正在尝试创建一个SwiftUI视图,该视图将充当我正在设计的应用程序的主页。作为此过程的一部分,我想在首页顶部包含一个醒目的搜索栏。但是,对于NavigationViewTabBar在SwiftUI中的工作方式,我可能有些困惑,因为当我导航到想要的子页面时,搜索栏不会消失。这是展示我在说什么的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变量,这在响应时间和正确传递更新的一半上有点慢。时间。看看:

broken

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

@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 }
)

该代码有时仅会触及NavigationLink的.onDisappear部分。为什么?

2 个答案:

答案 0 :(得分:1)

您的搜索栏不在导航视图中,这就是为什么它在导航后仍然可见的原因,因为导航是在 导航视图内进行的,而不是在全屏模式下进行。

因此,实现目标的方法可能如下(从原理上讲,因为提供的代码不可测试)

@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 }
}

答案 1 :(得分:0)

只需将搜索栏放入列表{}