我最终能够根据NavigationView
中的当前标签使用TabbedView
来更改onAppear()
的标题,但是我我很确定这不是解决之道:
struct SomeTabbedView : View {
@State private var selection = 0
@State private var title = "First"
var body: some View {
NavigationView {
TabbedView(selection: $selection) {
ContentView()
.tabItemLabel(
Text("First")
).tag(0).onAppear{
self.title = "First"
}
OtherView()
.tabItemLabel(
Text("Second")
).tag(1).onAppear{
self.title = "Second"
}
}.navigationBarTitle(Text(title))
}
}
}
简而言之,这严重违反了DRY原理。如果我们决定更改第一个视图,例如字符串“ First”,则当前的实现将需要在三个不同的位置重复该视图。
我考虑初始化一个字典数组并在View: Label
对上循环,但不仅我不确定这是正确的方法,而且我不确定如何继续执行它。也可以只包含一个带有标签的数组,但是如果我们想更改视图的顺序,则会造成另一个违规。
答案 0 :(得分:4)
您的顶级视图应为TabbedView
,并且每个选项卡都应具有自己的NavigationView
。这并不能解决.navigationBarTitle
和.tabItemLabel
都使用“ First”这一事实,但是实际上这是两个不同的事物,可以有所不同。
struct SomeTabbedView : View {
@State private var selection = 0
var body: some View {
TabbedView(selection: $selection) {
NavigationView {
ContentView()
.navigationBarTitle(Text("First"))
}
.tabItemLabel(Text("First"))
.tag(0)
NavigationView {
OtherView()
.navigationBarTitle(Text("Second"))
}
.tabItemLabel(Text("Second"))
.tag(1)
}.edgesIgnoringSafeArea(.top)
}
}
答案 1 :(得分:0)
我遇到了类似的问题,并通过创建类似于SwiftUI的视图包装器解决了该问题。 这基本上只是在vacawama's answer中添加DRYness:
struct NavigationTab<Title, Content>: View where Title: StringProtocol, Content: View {
var title: Title
var content: () -> Content
var body: some View {
NavigationView {
content()
.navigationBarTitle(Text(title))
}
.tabItemLabel(Text(title))
}
}
我将标记省略了,因为对我而言,在父视图中定义标记更有意义。您可以像这样使用它:
struct SomeTabbedView: View {
@State private var selection = 0
var body: some View {
TabbedView(selection: $selection) {
NavigationTab(title: "First") {
ContentView()
}
.tag(0)
NavigationTab(title: "Second") {
OtherView()
}
.tag(1)
}
}
}
如果您要在选项卡标签上方添加图像之类的其他详细信息,这显然会变得更加复杂,因为.navigationBarTitle()
需要一个Text实例。