从子视图 SwiftUI 中删除 UI 元素
Posted
技术标签:
【中文标题】从子视图 SwiftUI 中删除 UI 元素【英文标题】:Removing UI Element from Child View SwiftUI 【发布时间】:2020-02-04 23:14:07 【问题描述】:我正在尝试创建一个 SwiftUI 视图,该视图将充当我正在设计的应用程序的一种主页。作为其中的一部分,我想在主页顶部包含一个突出的搜索栏。但是,也许我对 NavigationView
和 TabBar
在 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
和@Binding
变量,以便在两个类之间传递它们的showHeader
变量,而且响应时间有点慢,并且在大约一半的时间里正确传递了更新。看看:
以及相关代码更改:(父视图)
@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
部分。为什么?
【问题讨论】:
Tabview 应该是您的顶部视图,如果您希望它显示在 FeedView 中,那么您的搜索应该在 FeedView 中。 【参考方案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
【讨论】:
我的 NavigationView 创建了另一组组件,然后将 NavigationLink 嵌入其中,我设法弄清楚如何在两个视图之间传递showHeader
变量。我现在遇到的问题是showHeader
状态似乎更新得太慢,有时在视图之间传递变量时根本无法更新。我会尽快更新帖子的更改以及新动画。【参考方案2】:
只需将搜索栏放入 List
【讨论】:
以上是关于从子视图 SwiftUI 中删除 UI 元素的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据从子视图传递到父视图到 SwiftUI 中的另一个子视图?
如何在 Swift UI 中删除 Picker 视图的灰色背景框