NavigationView height irregular swiftui - swift

I have a NavigationView and added a title. The problem is it looks weird when I run it.
var body: some View {
NavigationView {
Form {
Section {
Text("Hello World")
}
}
.navigationBarTitle("SwiftUI", displayMode: .inline)
}
}
The image looks weird. How can I make the navigation height look better just like UIKIt Navigation Bar

You have a double-nested NavigationView.
The view that you are showing in your example is already being presented from a NavigationView, so you don't need to create an additional view.
This is because the navigation view context is preserved when you use a NavigationLink.
Try removing it:
var body: some View {
Form {
Section {
Text("Hello World")
}
}
.navigationBarTitle("SwiftUI", displayMode: .inline)
}

Related

How to add TabView/anything under NavigationView?

I have this code to display NavigationView with toolbar, searchable:
var body: some View {
NavigationView {
TabView(selection: $selectedIndex) {
...
}
.tabViewStyle(.page(indexDisplayMode: .never))
.toolbar {
...
}
.searchable(text: $searchText)
}
}
I want to achieve a result with tabs similar to this:
However, I can't add anything except searchable and toolbar to the NavigationView.
I tried to make it with NavigationStack instead, TabView, and all ToolbarItemGroup placements - but no luck.
Please help, thank you.

Hide navigation bar in all the views, swiftUI

Currently I am working on SwiftUI project. I want to hide the build-in navbar. For this purpose I have to add these lines,
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
to each of view before pushing it into navigation controller in SwiftUI.
NavigationLink(destination:
ForgotPasswordView()
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
) {
Text("Forgot Password?")
.foregroundColor(.white)
}
Same will be done for LoginView
NavigationLink(destination:
LoginView()
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
) {
Text("Login")
.foregroundColor(.white)
}
So I need any generic method like we did in storyboard, hide it from root view and no child will have the navbar on top.
Updated for iOS 16+
You can wrap the view by creating a new view that accepts a child view, which adds all the necessary modifiers so that you don't have to repeat it every time.
struct NavigationWrapper<Content: View>: View {
#ViewBuilder var childView: Content
var body: some View {
childView
.toolbar(.hidden)
}
}
Now, you can use that wrapper for your navigation link's destination.
Here is an example:
struct ContentView: View {
var body: some View {
NavigationStack {
List {
ForEach(0..<10) { i in
NavigationLink("Row \(i)") {
NavigationWrapper {
Text("Detailed view for \(i)th row.")
}
}
}
}
.navigationTitle("RowGap")
.toolbar(.hidden)
}
}
}
It hides out the navigation bar and toolbar completely.

SwiftUI NavigationView nested in PageTabView wrong aligned on first appear

The NavigationViews inside my PageTabView are wrong aligned on first appear.
When i scroll to another page on my PageTabView and go back to the first page, the alignment is correct.
The content of the navigationview (red) is beneath the navigationbar on first appear.
Image of first appearance of the NavigationView
Image of the second appearance of the NavigationView
struct ContentView: View {
var body: some View {
TabView {
ForEach(0..<3) { index in
NavigationView {
Color.red
.navigationTitle("\(index). Page")
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
.tabViewStyle(.page)
}
}
Edit:
I want to build the layout of the rooms tab in the apple home app in compact mode. Therefore the TabView in the code above gets wrapped in another tabview without the pagetabviewstyle modifier.
This works, but the same extracted problem in the code above happens.
var body: some View {
NavigationView {
TabView {
ForEach(0..<3) { index in
Color.red
.navigationTitle("\(index). Page")
}
}
.tabViewStyle(.page)
}
}
Just moved NavigationView outside, it fixed the problem

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

SwiftUI Navigation through multiple screens

I'm a bit confused on how navigation works in SwiftUI. Does only the view starting the navigation need a NavigationView? I have one view with a NavigationView that has a NavigationLink to a second view. The second view then has a NavigationLink to a third and final view.
However, when my second view navigates to my third view, I get this message in the logs:
unbalanced calls to begin/end appearance transitions for <_TtGC7SwiftUI19UIHostingControllerVS_7AnyView_: 0x7f85d844bf90>.
I don't know if I'm handling navigation through multiple screens correctly and I'm getting some really odd behavior where pressing Next on my second screen takes me back to my first somehow...
//This is the link in my first view, my seconds link is the same except it does to my next step and the tag is different
NavigationLink(
destination: PasswordView(store: self.store),
tag: RegisterState.Step.password,
selection: .constant(store.value.step)
)
Navigation is a little bit tricky in SwiftUI, after creating one navigationview you don't need to create again in your 2nd or 3rd view. I am not sure how you creating it firstly. Here is an example how navigation is working.
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: SecondView()) {
Text("Show Second View")
}.navigationBarTitle("FirstView", displayMode: .inline)
}
}
}
}
struct SecondView: View {
var body: some View {
NavigationLink(destination: ThirdView()) {
Text("Show Third view")
}.navigationBarTitle("SecondView", displayMode: .inline)
}
}
struct ThirdView: View {
var body: some View {
Text("This is third view")
.navigationBarTitle("ThirdView", displayMode: .inline)
}
}