简体   繁体   English

SwiftUI,将标题设置为 NavigationView 内 TabView 的子视图不起作用

[英]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:演示:

带有 NavigationView 的 TabView

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. NavigationViewTabView只是在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.

相关问题 NavigationView 内的 SwiftUI TabView - SwiftUI TabView inside a NavigationView 当视图位于 SwiftUI 的 TabView 中时,NavigationView 标题不会出现 - NavigationView title doesn't appear when the views are in TabView in SwiftUI SwiftUI NavigationView + tabView 显示导航标题略微偏离屏幕 - SwiftUI NavigationView + tabView shows navigation title slightly off the screen SwiftUI - 在 NavigationView 中嵌套 TabView 时不显示导航栏标题 - SwiftUI - Navigation bar title not displayed when nesting TabView in NavigationView 在NavigationLink之后,在NavigationView内部,TabView内部显示NavigationBar。 SwiftUI - Displaying a NavigationBar, inside a NavigationView, inside a TabView, after a NavigationLink. SwiftUI SwiftUI NavigationView 转换不起作用 - SwiftUI NavigationView transition does not work SwiftUI - 如何将工具栏添加到 NavigationView 内的 TabView 选项卡? - SwiftUI - How to add toolbars to TabView tabs inside a NavigationView? 在 SwiftUI 中更改具有 NavigationView 和 ScrollView 的 TabView 内视图的背景颜色 - Change background color of View inside TabView having NavigationView and ScrollView in SwiftUI SwiftUI onAppear 在 TabView 内的 NavigationView 被调用两次 - SwiftUI onAppear called twice when NavigationView inside TabView SwiftUI 在 NavigationLink 视图中隐藏 TabView 栏 - SwiftUI Hide TabView bar inside NavigationLink views
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM