SwiftUI navigationView within Modal 'pushing' view down - swift

I currently have a modal view in SwiftUI that contains a series of NavigationLinks to different views. However, when I go to one of the other views it pushes all the content down leaving a empty forehead at the top of the view. How do I fix this?
I have included an example screenshot below.
To further clarify, there is a main view with a button that opens a Modal view. This modal contains a navigation view with a series of NavigationLink Buttons. When opening the navigation links within the modal, that is when the view is pushed down.

You have a large navigation bar, try to set navigationBar displayMode to .inline
.navigationBarTitle(Text(""), displayMode: .inline)

This probably happens because the view you push to from the NavigationView is also wrapped in a NavigationView.
struct SettingsView: View {
var body: some View {
NavigationView {
NavigationLink(destination: IAPView()) {
Text("In App Purchase")
}
}
}
}
You probably have this in the IAPView()
struct IAPView: View {
var body: some View {
NavigationView { <-- this is causing it
// your buttons here
}
}
}

You still have the default navigation bar space in your view. You need to add both these two view modifiers.
.navigationBarTitle("")
.navigationBarHidden(true)

Related

Navigationbar title is inline on pushed view, but was set to large

I want a large title in the navigationbar on a pushed view in SwiftUI and an inline title on the parent view.
When the parent navigation bar display mode is not set, it works:
Working without display mode on parent
But when I set the display mode in the parent view to inline, the title on the second screen is inline, instead of large. You can drag the list and the title will stay large. (You can see a small example in the code below)
With display mode to inline on the parent, the child is also inline.
Here is a small example:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: DestinationView()) {
Text("Next Screen")
}
.navigationBarTitle("Start screen", displayMode: .inline)
}
}
}
struct DestinationView: View {
var body: some View {
ScrollView {
VStack{
ForEach((1...10), id: \.self) {
Text("\($0)")
}
}
}
.navigationBarTitle("Second screen", displayMode: .large)
}
}
There are several post with similar questions:
https://www.reddit.com/r/iOSProgramming/comments/g2knmp/large_title_collapses_after_a_push_segue/
-> Same problem but with UIKit and we don't have prefersLargeTitles in SwiftUI.
Large title doesn't appear large
-> Same problem with UIKit and marked as answered with preferesLargeTitles.
Navigation bar title stays inline in iOS 15
-> Here was a fix from apple side, but it was a back navigation
just place .navigationViewStyle(.stack) in NavigationView in ContentView()

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

Hide Navigation Bar after NavigationLink is Tapped but keeping back button

I have two different views, one with a NavigationView and another one that i want without NavigationView but since i put it in a NavigationLink I can still see it with a button to go back to the first view.
Here's the code:
struct MainView: View {
var body: some View {
NavigationView {
NavigationLink(destination: SecondView()) {
Text("Go to SecondView")
.navigationBarTitle("MainView")
}
}
}
struct SecondView: View {
var body: some View {
Text("This is the SecondView")
}
I want to hide the Navigation Bar in the Second View but leaving a button to go back. I don't know if i can keep the button that was already displayed in the Navigation Bar or should i make a new one...in this case how can I add one to go back to the previous view?

SwiftUI - How to get a transparent status bar when in a tabbed view?

My app first root view is a tabbed view with two tabs. The second tab is a navigation view with a form. The setting can be summarised like this:
struct ContentView: View {
var body: some View {
TabView {
// First view
// ...
NavigationView {
Form {
// Form details
// ...
}
}
.tabItem {
// Text and image for the tab view item
}
}
}
}
Problem is that the form view's background is not white, it is slightly contrasted (as for grouped lists) and this creates a disgraceful separation with the status bar at the top:
This behaviour is not present in other app such as Apple ones. For instance the main view of Pages app is a tab view and the status bar remains transparent and of the same colour as the top bar title.
I'd like the same behaviour as the iPhone settings app, with a header colour matching the status bar view.
The problem here seems to be the tab view that takes control of the status bar appearance, if I remove it all goes normal.
Is there a way to get this behaviour inside a tab view?
You can wrap your TabView in a ZStack and set .edgesIgnoringSafeArea(.top) for your stack
var body: some View {
ZStack {
TabView {
Form {
Text("OK")
}
}.tabItem {
Text("Show")
}
}.edgesIgnoringSafeArea(.top)
}

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