SwiftUI,将标题设置为 NavigationView 内 TabView 的子视图不起作用 [英] SwiftUI, setting title to child views of TabView inside of NavigationView does not work

查看:29
本文介绍了SwiftUI,将标题设置为 NavigationView 内 TabView 的子视图不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我将 TabView 放入 NavigationView 是因为当用户进入具有自己底部操作栏的第二级详细信息"视图时,我需要隐藏底部标签栏.

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 托管的所有第一级列表"视图不再显示其标题.下面是一个示例代码:

But doing this leads to another issue: all the 1st level 'list' views hosted by TabView no longer display their titles. 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)
    }
}

我能做的是在根视图中有一个 @State var title 并将绑定传递给所有列表视图,然后让这些列表视图将它们的标题设置回根视图出现.但我只是觉得不太对劲,有没有更好的方法来做到这一点?感谢您的帮助.

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. But I just don't feel so right about it, is there any better way of doing this? Thanks for any help.

推荐答案

的想法是动态地将 TabView 选择与 NavigationView 内容结合起来.

The idea is to join TabView selection with NavigationView content dynamically.

演示:

这是描述方法的简化代码(使用您的视图).NavigationViewTabView 只是在 ZStack 中独立定位,而 NavigationView 的内容取决于 的选择TabView(内容只是存根),因此它们不会相互打扰.同样在这种情况下,可以根据某些条件隐藏/取消隐藏 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. 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.

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

这篇关于SwiftUI,将标题设置为 NavigationView 内 TabView 的子视图不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆