在SwiftUI中处理NavigationView内部的TabView的最佳方法

时间:2020-08-09 08:37:23

标签: ios swift swiftui navigationview tabview

我正在使用SwiftUI在Swift中开发一个应用。

我有这个设置,我将TabView放在NavigationView内,并在tabView上使用了NavigationBarTitle。之所以这样做,是因为如果将NavigationView放在TabView内,那么当我转到NavigationLink时,无法使Tab栏消失:使用swiftUI目前看来是不可能的。

当前设置问题是,因为我将.navigationBarTitle放在TabView上,所以更改标签视图时标题不会更改,并且由于某种原因我无法重置.navigationBarTitle。

这是解释我在说什么的代码:

ContentView:

NavigationView {
  TabView {
    SomeSubView().tabItem() { Text("SomeSubView") }
    Text("dummy2").tabItem() { Text("dummy2") }
    Text("dummy3").tabItem() { Text("dummy3") }
  }.navigationBarTitle("hello")
}

SomeSubView:

List(somearray) { element in
  NavigationLink(destination: elementDetails()) {
    SomeRowView()
  }
}

这是预览(上面的代码并非完全是我的代码,只是示例):

Preview

现在我想将.navigationBarTitle放在SomeSubView()中,如下所示:

List(somearray) { element in
  NavigationLink(destination: elementDetails()) {
    SomeRowView()
  }
}.navigationBarTitle("title2")

而不是为TabView选择全局标题。因此,在那种情况下,我会得到类似的东西:

NavigationView {
  TabView {
    SomeSubView().tabItem() { Text("SomeSubView") }
  }
}

然后我在SomeSubView()中选择一个.navigationBarTitle,但是它不起作用(标题栏只是不出现,而是选项卡标题已更改,这不是我想要的)。

所以我终于想到了这种设置:

@State private var title = Text("Default_Title")

var body: some View {
  NavigationView {
    TabView {
      SomeSubView().tabItem { Text("SomeSubView") }.onAppear { self.title = Text("new_title") }
      Text("dummy2").tabItem { Text("dummy2") }
      Text("dummy3").tabItem { Text("dummy3") }
    }.navigationBarTitle(title)
  }
}

这样,我可以在单击选项卡视图时动态更改标题,并且可以正常工作,但是我还需要为每个选项卡视图设置不同的.navigationBarItems,因此我对的前导和尾随参数进行了相同的操作。 navigationBarItems,如下所示:

@State private var title = Text("Default_Title")
@State private var leading = NavBar_leading(type: "FirstView")
@State private var trailing = NavBar_trailing(type: "FirstView")

var body: some View {
  NavigationView {
    TabView {
      SomeSubView().tabItem { Text("SomeSubView") }.onAppear {
          self.title = Text("new_title")
          self.leading = NavBar_leading(type: "FirstView")
          self.trailing = NavBar_trailing(type: "FirstView")
      }
      Text("dummy2").tabItem { Text("dummy2") }
      Text("dummy3").tabItem { Text("dummy3") }
    }.navigationBarTitle(title).navigationBarItems(leading: leading, trailing: trailing)
  }
}

如您所见,我动态更新.navigationBarItems的前导参数和尾随参数,以为每个选项卡视图设置不同的项(在我的情况下为按钮)。 NavBar_leading和NavBar_trailing视图根据我传递的参数返回Button文本类型,如下所示:

struct NavBar_leading: View {
    var type: String
    
    var body: some View {
        if type == "FirstView" {
            return Button(action: {
                print("hello1 empty")
                }) {
                    Text("")
            }
        } else if (type == "SecondView") {
            return Button(action: {
                print("hello2")
                }) {
                    Text("SomeButton")
            }
        } else {
            return Button(action: {
                print("hello3 empty")
                }) {
                    Text("")
            }
        }
    }
}

现在的问题是我想有时从同一个NavBar_leading视图返回一个按钮文本,但有时返回一个按钮图像,但是Swift不允许我从同一视图返回不同的类型。我以为“按钮”视图是一种类型,但似乎根据您放入的内容,它会变成另一种类型。

我听说Any视图类型在Swift中不是一个好习惯,并且会影响性​​能,所以我正在寻找一种方法来实现我想要的功能。

我解释了所有内容,因为我愿意接受任何其他建议,例如,如果我可以做得更好,那么我可以从头开始重新开始,所以这是我的问题:

  • 使用NavigationView内的TabView处理我是否需要做一个好主意?还有我不知道的更好的东西吗?
  • 是否还有其他方法可以为每个选项卡视图显示不同的标题,而不是像我一样更新全局标题?
  • 有什么方法可以从视图中返回不同的Button类型,而无需使用Any视图类型?我能做得更好吗?

谢谢

0 个答案:

没有答案