Navigation Bar Title not appearing in simulator SwiftUI - swift

I'm not sure if Xcode has a bug or if I'm wrong, but I have mi Home() view which has a TabView, this tab view allow me to navigate to differences views, while I was coding my SettingsView() I notice than in canvas I can see the NavigationBarTitle, but then I run simulator, the title don't appear.
Home() View
struct Home: View {
#State var tabPredeterminado:Int = 1
var body: some View {
TabView(selection: $tabPredeterminado) {
SettingsView()
.tabItem{
Image(systemName: "gearshape.fill")
Text("Settings")
}.tag(3)
}
.navigationBarBackButtonHidden(true)
}
}
SettingsView()
var body: some View {
NavigationStack {
List {...}
.navigationBarTitle("Settings")
}
}
}
Simulator

Related

NavigationStack inside TabView inside NavigationStack does not work

I want to have a root NavigationStack that lets the user navigate around a SwiftUI app, including to a TabView with tabs that have their own navigation stack. Unfortunately, this seems to not work at all (xcode 14.2, iOS 16).
The following example demonstrates the issue. When you attempt to navigate inside the tab view navigation stack, the tabs disappear and then the app goes into a broken state where navigation basically stops working entirely.
import SwiftUI
struct TabsView: View {
var body: some View {
TabView {
NavigationStack {
ZStack {
NavigationLink("Navigate to child tab", value: 1)
}
.navigationDestination(for: Int.self) { screen in
Text("Tab child \(screen)")
}
}
.tabItem {
Label("Screen 1", systemImage: "house")
}
Text("Screen 2")
.tabItem {
Label("Screen 2", systemImage: "house")
}
}
}
}
struct ContentView: View {
var body: some View {
NavigationStack {
VStack {
NavigationLink("Show Tabs", value: "tabs")
}
.navigationDestination(for: String.self) { screen in
if screen == "tabs" {
TabsView()
} else {
Text("?")
}
}
}
}
}
How can I make this work?
Use NavigationView in ContentView. Apple has problems with NavigationStack in hierarchy of NavigationStack.

SwiftUI: Problem with Tabviews and NavigationViews when TabViews is not main page

Good afternoon,
I have a problem on my app with the NavigationViews. When launching the app for the very first time, users are displayed a LogIn and Sign Up page (which does not have a TabView) and once they Log-In they are directed to a TabView with different sections (Home, Chats, etc...).
The main problem that I have is that when changing from the Login view to the TabView,the NavigationTitle that is set is only that of HomeView and when changing to a different tab, the title does not change. How could I solve this problem, how do other apps deal with this?
Thank you.
File LoginView
import SwiftUI
struct LoginView: View {
var body: some View{
NavigationView{
NavigationLink(destination: TabView, label: Text("Login")
}
}
}
File TabView
import Swift UI
struct TabView: View {
var body: some View{
TabView {
HomeView()
.tabItem{
//Not relevant code
}
ChatView()
.tabItem{
//Not relevant code
}
}
}
}
File HomeView
import SwiftUI
struct HomeView: View {
var body: some View {
ZStack{
//Not relevant code
}
.navigationBarTitle("Home")
}
}
File ChatsView
import SwiftUI
struct ChatsView: View {
var body: some View {
ZStack{
//Not relevant code
}
.navigationBarTitle("Chats")
}
}
struct ContentView: View {
enum Tab {
case homeView
case chatView
}
#State var selecion: Tab = .homeView
#State var title = "House"
var body: some View{
TabView(selection: $selecion){
HomeView()
.tabItem{
//Not relevant code
Image(systemName: "house")
}
.tag(Tab.homeView)
.onAppear {
title = "House"
}
ChatsView()
.tabItem{
//Not relevant code
Image(systemName: "star")
}
.tag(Tab.chatView)
.onAppear {
title = "Chat"
}
}
.navigationTitle(title)
}
}

Taking Top Space When Adding Tab Bar in SwiftUI

I am integrating Side Menu in my SwiftUI app. The side menu is working fine. The problem I am getting is I have a tab bar at the bottom, and when I open my side menu screen, it is taking some space from the top and I am not getting why it is getting that space. This is what I am getting:
And when I open Debug View Hierarchy, it is showing me this:
This is my code for my home screen:
struct HomeView: View {
#State var menuOpen: Bool = false
var body: some View {
Zstack {
ZStack {
HStack {
if !self.menuOpen {
Button {
print("side menu tapped")
self.menuOpen.toggle()
} label: {
Image("sideMenuButton")
.resizable()
.frame(width: 24, height: 24)
}.padding()
}
Spacer()
}
Text("Home")
.font(.custom(Poppins.semiBold.rawValue, size: 17))
.foregroundColor(Color(ColorName.appBlue.rawValue))
}
ZStack {
SideMenu(width: 300,
isOpen: self.menuOpen,
menuClose: self.openMenu)
}
}
}.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
func openMenu() {
self.menuOpen.toggle()
}
}
This is working fine when I use it without tab bar. Without tab bar it looks like this:
My code for tab bar controller is:
struct TabBarControllerView: View {
#State private var tabSelection = 0
var body: some View {
TabView(selection: $tabSelection) {
HomeView()
.tabItem {
Label("Home", image: tabSelection == 0 ? ImageName.home.rawValue : ImageName.silverHome.rawValue)
}
.tag(0)
MyAccountView()
.tabItem {
Label("Claims", image: tabSelection == 1 ? ImageName.claims.rawValue : ImageName.silverClaims.rawValue)
}
.tag(1)
}.accentColor(Color(ColorName.appBlue.rawValue))
}
}
struct TabBarControllerView_Previews: PreviewProvider {
static var previews: some View {
TabBarControllerView()
}
}
Does anyone knows why is it getting the top space? I tried .ignoresSafeArea() and also gave padding in negative, it went to top but the side menu did not tapping because it is getting under that space.
I am been stuck in this for 2 days, any help will be appreciated.
TabView comes with Navigation Bar up top. There is a simple solution by adding .navigationBarHidden(true).
See this post: SwiftUI how to hide navigation bar with TabView
Note: Also in the future give a proper minimum amount of code to reproduce the behavior. Your current code given relies on other components and isn't runnable by itself on a fresh project.
Update:
I created a minimum project to test this and this code works fine with me:
import SwiftUI
#main
struct testApp: App {
var body: some Scene {
WindowGroup {
TabBarView()
}
}
}
struct TabBarView: View {
#State private var tabSelection = 0
var body: some View {
TabView(selection: $tabSelection) {
HomeView()
.tabItem {
Label("Home", systemImage: "house")
}
.tag(0)
}
}
}
struct HomeView: View {
var body: some View {
ZStack {
Rectangle().foregroundColor(.green)
VStack {
HStack {
Spacer()
Button {
print("side menu tapped")
} label: {
Image(systemName: "pencil")
.resizable()
.frame(width: 24, height: 24)
}.padding()
Spacer()
}
Spacer()
}
}
}
}
Given that this code works fine and the issue is not here, minimum working code sample is needed from OP.

SwiftUI: Problems with List inside TabViews inside NavigationView

I want to place a TabView inside a NavigationView with different titles depending on the selected tab. Inside those tabs I want to place a List view. See the code below:
struct ContentView: View {
#State private var selection = 1
var body: some View {
TabView(selection:$selection) {
Page_1()
.tabItem {
Image(systemName: "book")
Text("Page 1")
}
.tag(1)
Page_2()
.tabItem {
Image(systemName: "calendar")
Text("Page 2")
}
.tag(2)
}
}
}
struct Page_1: View {
#State var selectedTab = "1"
var body: some View {
NavigationView {
TabView(selection: $selectedTab) {
List {
ForEach(0..<20){i in
Text("Test")
}
}
.tag("1")
.navigationBarTitle("Page 1 Tab 1")
List {
ForEach(0..<20){i in
Text("Test")
}
}
.tag("2")
.navigationBarTitle("Page 1 Tab 2")
}
.tabViewStyle(.page(indexDisplayMode: .never))
.ignoresSafeArea(.all)
.background()
}
}
}
struct Page_2: View {
#State var selectedTab = "1"
var body: some View {
NavigationView {
TabView(selection: $selectedTab) {
List {
ForEach(0..<20){i in
Text("Test")
}
}
.tag("1")
.navigationBarTitle("Page 2 Tab 1")
List {
ForEach(0..<20){i in
Text("Test")
}
}
.tag("2")
.navigationBarTitle("Page 2 Tab 2")
}
.tabViewStyle(.page)
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.ignoresSafeArea()
.background()
}
}
}
The problem is that when the Pages first appear the lists inside their TabViews seem to be placed slightly too low and then move up. You can see this especially when you switch tabs like here:
After switching back and forth between the tabs they are placed correctly until I freshly start the app again. Would really appreciate your help!:)
Edit
As suggested I tried to put the NavigationViews inside the TabView. That solves the problem with the wrong positioning. However, it leads to the views not being shown at all before I switch back and forth between them. You can see what that looks like in the picture below:

NavigationView inside a TabView Swift UI

I'm just picking up SwiftUI after a long break but I don't understand why I can't place a Navigation View within a Tab View.
I want my Navigation View to be a .tabItem so the view appears as part of the main app navigation so I'm trying this :
struct ContentView: View {
var body: some View {
TabView {
NavigationView {
.tabItem {
Text("Home")
}
Text("Tab bar test")
.navigationBarTitle("Page One")
}
}
This doesn't work with error message
Cannot infer contextual base in reference to member 'tabItem'
But when I try this
var body: some View {
TabView {
NavigationView {
Text("Tab bar test")
.navigationBarTitle("Page One")
}
}
.tabItem {
Image(systemName: "1.circle")
Text("Home")
}
}
It builds fine but the tab bar doesn't show up.
My primary question which I'm hoping would be useful to others, is ...
Why can't I make a make a Navigation View a tab bar item by nesting .tabItem directly inside the Navigation View (as per my first example)?
I think it's a similar question to this one but there's no code there. And then quite similar to this one but they seem to be using .tabItem directy with ContentView like I want to with NavigationView but that isn't building!?
I'm probably misunderstanding something simple but I don't get this at all at the moment.
Do this for a better overview:
ContentView:
struct ContentView : View {
var body: some View {
TabView {
FirstView()
.tabItem {
Image(systemName: "folder.fill")
Text("Home")
}
SecondView()
.tabItem {
Image(systemName: "folder.fill")
Text("SecondView")
}
}
}
}
FirstView
struct FirstView: View {
var body: some View {
NavigationView {
Text("FirstView")
.navigationBarTitle("Home")
}
}
}
}
SecondView
struct SecondView: View {
var body: some View {
NavigationView {
Text("SecondView")
.navigationBarTitle("Home")
}
}
}
}
.tabItem should be used as a modifier on the view that represents that tab.
In the first example, this doesn't work because of a syntax error -- you're trying to use it on the opening of a closure in NavigationView {, when instead you want it on the outside of the closing brace: NavigationView { }.tabItem(...)
In the second example, you're using .tabItem as a modifier on the entire TabView instead of the NavigationView.
Both of your examples may have revealed what was going on more obviously if you indent your code so that you can see the hierarchy. Trying selecting your code in Xcode and using Ctrl-I to get Xcode to properly format it for you.
Here's a working version:
struct ContentView : View {
var body: some View {
TabView {
NavigationView {
Text("Tab bar test")
.navigationBarTitle("Page One")
}
.tabItem { //note how this is modifying `NavigationView`
Image(systemName: "1.circle")
Text("Home")
}
}
}
}