[英]SwiftUI, setting title to child views of TabView inside of NavigationView does not work
Why I am putting TabView into a NavigationView is because I need to hide the bottom tab bar when user goes into 2nd level 'detail' views which have their own bottom action bar.为什么我将 TabView 放入 NavigationView 是因为当用户进入具有自己底部操作栏的第二级“详细信息”视图时,我需要隐藏底部标签栏。
But doing this leads to another issue: all the 1st level 'list' views hosted by TabView no longer display their titles.但是这样做会导致另一个问题:TabView 托管的所有第一级“列表”视图不再显示其标题。 Below is a sample code:
下面是一个示例代码:
import SwiftUI
enum Gender: String {
case female, male
}
let members: [Gender: [String]] = [
Gender.female: ["Emma", "Olivia", "Ava"], Gender.male: ["Liam", "Noah", "William"]
]
struct TabItem: View {
let image: String
let label: String
var body: some View {
VStack {
Image(systemName: image).imageScale(.large)
Text(label)
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
TabView {
ListView(gender: .female).tag(0).tabItem {
TabItem(image: "person.crop.circle", label: Gender.female.rawValue)
}
ListView(gender: .male).tag(1).tabItem {
TabItem(image: "person.crop.circle.fill", label: Gender.male.rawValue)
}
}
}
}
}
struct ListView: View {
let gender: Gender
var body: some View {
let names = members[gender]!
return List {
ForEach(0..<names.count, id: \.self) { index in
NavigationLink(destination: DetailView(name: names[index])) {
Text(names[index])
}
}
}.navigationBarTitle(Text(gender.rawValue), displayMode: .inline)
}
}
struct DetailView: View {
let name: String
var body: some View {
ZStack {
VStack {
Text("profile views")
}
VStack {
Spacer()
HStack {
Spacer()
TabItem(image: "pencil.circle", label: "Edit")
Spacer()
TabItem(image: "minus.circle", label: "Delete")
Spacer()
}
}
}
.navigationBarTitle(Text(name), displayMode: .inline)
}
}
What I could do is to have a @State var title in the root view and pass the binding to all the list views, then have those list views to set their title back to root view on appear.我能做的是在根视图中有一个@State var 标题并将绑定传递给所有列表视图,然后让这些列表视图将它们的标题设置回根视图。 But I just don't feel so right about it, is there any better way of doing this?
但我只是觉得不太对劲,有没有更好的方法来做到这一点? Thanks for any help.
谢谢你的帮助。
The idea is to join TabView
selection with NavigationView
content dynamically.这个想法是动态地将
TabView
选择与NavigationView
内容结合起来。
Demo:演示:
Here is simplified code depicting approach (with using your views).这是描述方法的简化代码(使用您的视图)。 The
NavigationView
and TabView
just position independently in ZStack
, but content of NavigationView
depends on the selection of TabView
(which content is just stub), thus they don't bother each other. NavigationView
和TabView
只是在ZStack
独立定位,但NavigationView
内容取决于TabView
的选择(哪些内容只是存根),因此它们不会相互打扰。 Also in such case it becomes possible to hide/unhide TabView
depending on some condition - in this case, for simplicity, presence of root list view.同样在这种情况下,可以根据某些条件隐藏/取消隐藏
TabView
- 在这种情况下,为简单起见,存在根列表视图。
struct TestTabsOverNavigation: View {
@State private var tabVisible = true
@State private var selectedTab: Int = 0
var body: some View {
ZStack(alignment: .bottom) {
contentView
tabBar
}
}
var contentView: some View {
NavigationView {
ListView(gender: selectedTab == 0 ? .female : .male)
.onAppear {
withAnimation {
self.tabVisible = true
}
}
.onDisappear {
withAnimation {
self.tabVisible = false
}
}
}
}
var tabBar: some View {
TabView(selection: $selectedTab) {
Rectangle().fill(Color.clear).tag(0).tabItem {
TabItem(image: "person.crop.circle", label: Gender.female.rawValue)
}
Rectangle().fill(Color.clear).tag(1).tabItem {
TabItem(image: "person.crop.circle.fill", label: Gender.male.rawValue)
}
}
.frame(height: 50) // << !! might be platform dependent
.opacity(tabVisible ? 1.0 : 0.0)
}
}
This maybe a late answer, but the TabView items need to be assigned tag
number else binding selection
parameter won't happen.这可能是一个迟到的答案,但需要为 TabView 项目分配
tag
号,否则绑定selection
参数不会发生。 Here is how I do the same thing on my project:这是我如何在我的项目中做同样的事情:
@State private var selectedTab:Int = 0
private var pageTitles = ["Home", "Customers","Sales", "More"]
var body: some View {
NavigationView{
TabView(selection: $selectedTab, content:{
HomeView()
.tabItem {
Image(systemName: "house.fill")
Text(pageTitles[0])
}.tag(0)
CustomerListView()
.tabItem {
Image(systemName: "rectangle.stack.person.crop.fill")
Text(pageTitles[1])
}.tag(1)
SaleView()
.tabItem {
Image(systemName: "tag.fill")
Text(pageTitles[2])
}.tag(2)
MoreView()
.tabItem {
Image(systemName: "ellipsis.circle.fill")
Text(pageTitles[3])
}.tag(3)
})
.navigationBarTitle(Text(pageTitles[selectedTab]),displayMode:.inline)
.font(.headline)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.