title: Best way to handle a TabView inside a NavigationView in SwiftUI
body: <p>I am developing an app in Swift with SwiftUI.</p>
  <p>I have this setup where I put a TabView inside a NavigationView and used the navigationBarTitle on the tabView. I did this because if I put the NavigationView inside the TabView, I cannot make the Tab bar disappear when I go to a NavigationLink: it seems currently impossible with swiftUI.</p>
  <p>The current problem with my setup is that since I put the .navigationBarTitle on the TabView, the title does not change when I change the tab view and I cannot reset the .navigationBarTitle on the subview for some reason.</p>
  <p>Here is a code to explain what I am saying:</p>
  <p>ContentView :</p>
  <pre class="lang-swift prettyprint-override"><code>NavigationView {
    TabView {
      SomeSubView().tabItem() { Text(&quot;SomeSubView&quot;) }
      Text(&quot;dummy2&quot;).tabItem() { Text(&quot;dummy2&quot;) }
      Text(&quot;dummy3&quot;).tabItem() { Text(&quot;dummy3&quot;) }
    }.navigationBarTitle(&quot;hello&quot;)
  }
  </code></pre>
  <p>SomeSubView:</p>
  <pre class="lang-swift prettyprint-override"><code>List(somearray) { element in
    NavigationLink(destination: elementDetails()) {
      SomeRowView()
    }
  }
  </code></pre>
  <p>Here is a preview (the code above isn't <strong>exactly</strong> my code but just an example):</p>
  <p><a href="https://i.stack.imgur.com/e97ol.png" rel="noreferrer">Preview</a></p>
  <p>Now I woukd like to put the .navigationBarTitle inside the SomeSubView() like this:</p>
  <pre class="lang-swift prettyprint-override"><code>List(somearray) { element in
    NavigationLink(destination: elementDetails()) {
      SomeRowView()
    }
  }.navigationBarTitle(&quot;title2&quot;)
  </code></pre>
  <p>Instead of choosing a global title for the TabView. So in that case I would have something like:</p>
  <pre class="lang-swift prettyprint-override"><code>NavigationView {
    TabView {
      SomeSubView().tabItem() { Text(&quot;SomeSubView&quot;) }
    }
  }
  </code></pre>
  <p>Then I choose a .navigationBarTitle inside the SomeSubView() but it doesn't work (the title bar just does not appear, instead the tab title is changed and that's not what I want).</p>
  <p>So I finally came up with this kind of setup:</p>
  <pre class="lang-swift prettyprint-override"><code>@State private var title = Text(&quot;Default_Title&quot;)
  
  var body: some View {
    NavigationView {
      TabView {
        SomeSubView().tabItem { Text(&quot;SomeSubView&quot;) }.onAppear { self.title = Text(&quot;new_title&quot;) }
        Text(&quot;dummy2&quot;).tabItem { Text(&quot;dummy2&quot;) }
        Text(&quot;dummy3&quot;).tabItem { Text(&quot;dummy3&quot;) }
      }.navigationBarTitle(title)
    }
  }
  </code></pre>
  <p>This way, I can dynamically change the title when I click on a tab view and it works fine but I also need to set different .navigationBarItems for each tab view so I did the same thing for the leading and trailing parameters of .navigationBarItems, like this:</p>
  <pre class="lang-swift prettyprint-override"><code>@State private var title = Text(&quot;Default_Title&quot;)
  @State private var leading = NavBar_leading(type: &quot;FirstView&quot;)
  @State private var trailing = NavBar_trailing(type: &quot;FirstView&quot;)
  
  var body: some View {
    NavigationView {
      TabView {
        SomeSubView().tabItem { Text(&quot;SomeSubView&quot;) }.onAppear {
            self.title = Text(&quot;new_title&quot;)
            self.leading = NavBar_leading(type: &quot;FirstView&quot;)
            self.trailing = NavBar_trailing(type: &quot;FirstView&quot;)
        }
        Text(&quot;dummy2&quot;).tabItem { Text(&quot;dummy2&quot;) }
        Text(&quot;dummy3&quot;).tabItem { Text(&quot;dummy3&quot;) }
      }.navigationBarTitle(title).navigationBarItems(leading: leading, trailing: trailing)
    }
  }
  </code></pre>
  <p>As you can see, I dynamically update the leading and trailing parameters of .navigationBarItems to set different items (buttons in my case) for each tab view. The NavBar_leading and NavBar_trailing view return a Button text type depending on the parameter I passed, like this:</p>
  <pre class="lang-swift prettyprint-override"><code>struct NavBar_leading: View {
      var type: String
      
      var body: some View {
          if type == &quot;FirstView&quot; {
              return Button(action: {
                  print(&quot;hello1 empty&quot;)
                  }) {
                      Text(&quot;&quot;)
              }
          } else if (type == &quot;SecondView&quot;) {
              return Button(action: {
                  print(&quot;hello2&quot;)
                  }) {
                      Text(&quot;SomeButton&quot;)
              }
          } else {
              return Button(action: {
                  print(&quot;hello3 empty&quot;)
                  }) {
                      Text(&quot;&quot;)
              }
          }
      }
  }
  </code></pre>
  <p>Now the problem is that I want to return sometimes a Button Text, but sometimes a Button Image from the same NavBar_leading view but Swift does not allow me to have different types returned from the same view. I thought the Button view was one type but it seems that depending on what you put inside, it becomes another type.</p>
  <p>I heard that the Any view type isn't a good practice in Swift and has performance impact, so I'm looking for a way to achieve what I want here.</p>
  <p>I explained everything because I am open to any other suggestion, like if I can do something totally better I am open to restart from scratch, so here are my questions:</p>
  <ul>
  <li>Is my handling with the TabView inside the NavigationView a good idea for what I needed to do? Is there something better that I do not know?</li>
  <li>Is there any other way to display a different title for each tab view instead of a global title that I update like I did?</li>
  <li>Is there any way to return different Button types from a view without using an Any view type? Anything better that I can do?</li>
  </ul>
  <p>Thank you</p>