Hide Navigation bar for `TabView` not working - swiftui

In swiftUI, iOS14. I can not hide the navigation bar of TabView. Here is my code:
struct ContentView: View {
var body: some View {
NavigationView {
TabView() {
List {
Text("Hi!")
Text("How are you?")
}
}
.navigationTitle("")
.navigationBarHidden(true) // not working!!
}
}
}
Is this a bug? How to resolve this problem?

You need to move .navigationBarHidden(true) inside to TabView.
struct ContentView: View {
var body: some View {
NavigationView {
TabView() {
List {
Text("Hi!")
Text("How are you?")
}
.navigationBarHidden(true) //<= here
}
}
}
}

Related

How can I Hide TabBar in specific Views, in iOS 15 using SwiftUI

I need my TabBar to disappear if I click on a NavigationLink.
I know you can achieve that in iOS 14 with the following code:
NavigationView{
TabView{
View1().tabItem {
Image(systemName: "house.fill")
Text("Home")
}
}
}
And View1:
struct View1: some View {
var body: some View {
NavigationView{
NavigationLink(destination: Text("New Page without the Tabbar")) {
Text("Link")
}
}
}
}
But somehow this don't works in iOS 15...
Are there any other workarounds?
You could try using only one NavigationView, like in this example:
import SwiftUI
#main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
TabView {
View1().tabItem {
Image(systemName: "house.fill")
Text("Home")
}
}
}
}
}
struct View1: View {
var body: some View {
// ---> here no NavigationView
NavigationLink(destination: Text("New Page without the Tabbar")) {
Text("Link")
}
}
}

.confirmationDialog inside of .swipeActions does not work, iOS 15

With regards to iOS 15, Xcode 13; I am wondering if this is a bug, not properly implemented, or a planned non-functional feature...
With a list that has a .swipeActions that calls a .confirmationDialog the confirmation dialog does not show.
See example:
import SwiftUI
struct ContentView: View {
#State private var confirmDelete = false
var body: some View {
NavigationView {
List{
ForEach(1..<10) {_ in
Cell()
}
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
confirmDelete.toggle()
} label: {
Label("Delete", systemImage: "trash")
}
.confirmationDialog("Remove this?", isPresented: $confirmDelete) {
Button(role: .destructive) {
print("Removed!")
} label: {
Text("Yes, Remove this")
}
}
}
}
}
}
}
struct Cell: View {
var body: some View {
Text("Hello")
.padding()
}
}
Misconfiguration:
The view modifier .confirmationDialog needs to be added to the view that is outside of the .swipeActions view modifier. It works when configured properly as shown below:
import SwiftUI
struct ContentView: View {
#State private var confirmDelete = false
var body: some View {
NavigationView {
List{
ForEach(1..<10) {_ in
Cell()
}
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
confirmDelete.toggle()
} label: {
Label("Delete", systemImage: "trash")
}
}
//move outside the scope of the .swipeActions view modifier:
.confirmationDialog("Remove this?", isPresented: $confirmDelete) {
Button(role: .destructive) {
print("Removed!")
} label: {
Text("Yes, Remove this")
}
}
}
}
}
}
struct Cell: View {
var body: some View {
Text("Hello")
.padding()
}
}

SwiftUI UINavigationBar does not ignore the top safe area. How to get rid of empty space on the top?

Code I used to create an example of this navigation bar:
struct ContentView: View {
init() {
let defaultAppearance = UINavigationBarAppearance()
defaultAppearance.configureWithOpaqueBackground()
defaultAppearance.backgroundColor = .red
UINavigationBar.appearance().standardAppearance = defaultAppearance
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
}
var body: some View {
ParentView()
}
}
struct ParentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: DetailView()) {
Text("Tap here")
}
}
.navigationBarTitle("", displayMode: .inline)
.navigationBarHidden(true)
.edgesIgnoringSafeArea(.all)
}
}
}
struct DetailView: View {
var body: some View {
VStack {
Text("Detail View")
}
.edgesIgnoringSafeArea(.all)
}
}
It doesn't matter where I'm putting .edgesIgnoringSafeArea(.all) it doesn't work. Is there another way to tell Navigation Bar to ignore the safe area?
If it's not the safe area problem, then I need to make the whole navigation bar to have the same height of UINavigationBarContentView displayed in UI Hierarchy:

Why do I exit my TabView when navigating to a child view?

Question. Why do I exit my TabView when navigating to a view that is a child of a TabView? I hope I am being clear, but the code below is ready to be copy and pasted and notice how when I navigate to UnrelatedView I exit my tabView...
Additional context: The root view ContentView in this case is embedded inside of a NavigationView in the App.swift file
import SwiftUI
struct ContentView: View {
var body: some View {
TabView {
ViewA()
.tabItem {
Text("A")
}
ViewB()
.tabItem {
Text("B")
}
ViewC()
.tabItem {
Text("C")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ViewA: View {
var body: some View {
NavigationLink(destination: UnrelatedView()) {
Text("ViewA")
}
}
}
struct ViewB: View {
var body: some View {
Text("ViewB")
}
}
struct ViewC: View {
var body: some View {
Text("ViewC")
}
}
struct UnrelatedView: View {
var body: some View {
NavigationView {
Text("Unrelated View")
}
}
}
You need to wrap your navigation in NavigationViews.
struct ViewA: View {
var body: some View {
NavigationView {
NavigationLink(destination: UnrelatedView()) {
Text("ViewA")
}
}
}
}

How to go to another view with button click

I have a button in my code and I have a file called LogindView.swift
I cannot get the code to open another view file when clicking on the button.
Can anybody give me an example on how to do it.
In my button action I have tried to write LogindView() but i just gives me a warning.
"Result of 'LogindView' initializer is unused"
Button(action: {
// Do action
LogindView()
}, label: {
//** Label text
Text("Logind")
.font(.headline)
.padding(.all)
.foregroundColor(Color.white)
})
.background(Color.blue)
You essentially have 3 options to transition between views depending on your needs.
First, you can use a NavigationView. This will provide a back button and will allow the user to go back. Note that there are some bugs currently when you don't put the NavigationLink inside of a List as per https://stackoverflow.com/a/57122621/3179416
import SwiftUI
struct MasterView: View {
var body: some View {
NavigationView {
List {
NavigationLink(destination: LoginView()) {
Text("Login")
}
}
.navigationBarTitle(Text("Master"))
}
}
}
struct LoginView: View {
var body: some View {
Text("Login View")
}
}
Second, you can present a modal using .sheet. This will present a modal that appears on top of the current view but it can be dismissed by the user by dragging it down.
import SwiftUI
struct MasterView: View {
#State var isModal: Bool = false
var body: some View {
Button("Login") {
self.isModal = true
}.sheet(isPresented: $isModal, content: {
LoginView()
})
}
}
struct LoginView: View {
var body: some View {
Text("Login View")
}
}
Third, you can just use an if statement to change the current view to your Login View like so
import SwiftUI
struct MasterView: View {
#State var showLoginView: Bool = false
var body: some View {
VStack {
if showLoginView {
LoginView()
} else {
Button("Login") {
self.showLoginView = true
}
}
}
}
}
struct LoginView: View {
var body: some View {
Text("Login View")
}
}
If you would like to animate this, so that the transition doesn't appear so abruptly, you can also do this:
import SwiftUI
struct MasterView: View {
#State var showLoginView: Bool = false
var body: some View {
VStack {
if showLoginView {
LoginView()
.animation(.spring())
.transition(.slide)
} else {
Button("Login") {
withAnimation {
self.showLoginView = true
}
}.animation(.none)
}
}
}
}
struct LoginView: View {
var body: some View {
Text("Login View")
}
}
You can use navigation link instead button
var body: some View {
VStack {
Text("Title")
.font(.headline)
Image("myimage").clipShape(Circle())
Text("mytext").font(.title)
NavigationLink(destination: AnotherView()) {
Image(systemName: "person.circle").imageScale(.large)
}
}
}