Home > Software engineering >  SwiftUI - Remove extra space in NavigationBar after transitioning back to Home view from subview
SwiftUI - Remove extra space in NavigationBar after transitioning back to Home view from subview

Time:11-03

I am new to SwiftUI and have run into a little challenge. Whenever I go from my Home view to a sub-view and then back to the Home view, I am seeing extra space created in the Navigation view (see linked GIF). I was wondering if anyone had any advice - thanks in advance!

Here is the Home Screen:

struct Home: View {

@State private var view2 = false

var body: some View {
    NavigationView {
        VStack {
            Text("Home View!")
                .padding()
            
            NavigationLink(destination: View2(), isActive: $view2) { }
            
            Button {
                self.view2 = true
            } label: {
                Text("Go to next view")
            }
            
        }
        .navigationTitle("Home")
        
    }
    
} }

Here is the sub-new (View2):

struct View2: View {

@State private var home = false

var body: some View {
    VStack {
        Text("This is View 2")
            .padding()
        
        NavigationLink(destination: Home().navigationBarBackButtonHidden(true), isActive: $home) { }
        
        Button {
            self.home = true
        } label: {
            Text("Go to Home view")
        }
        
    }
    .navigationTitle("View 1")
} }

Link to GIF: Visual GIF of the issue

CodePudding user response:

Every time you push a new Home via a NavigationLink, you're adding another NavigationView to the hierarchy, since Home has a NavigationView in it.

To avoid that, you could separate the NavigationView out and instead link to View:

struct Home: View {
    var body: some View {
        NavigationView {
            View1() //<-- Here
        }
    }
}

struct View1 : View {
    @State private var view2 = false
    
    var body: some View {
        VStack {
            Text("Home View!")
                .padding()
            
            NavigationLink(destination: View2(), isActive: $view2) { }
            
            Button {
                self.view2 = true
            } label: {
                Text("Go to next view")
            }
            
        }
        .navigationTitle("Home")
    }
}

struct View2: View {
    
    @State private var home = false
    
    var body: some View {
        VStack {
            Text("This is View 2")
                .padding()
            
            NavigationLink(destination: View1() //<-- Here
.navigationBarBackButtonHidden(true), isActive: $home) { }
            
            Button {
                self.home = true
            } label: {
                Text("Go to Home view")
            }
            
        }
        .navigationTitle("View 2")
    }
}

That being said, I'm a little skeptical of the strategy here. It seems like instead of pushing a new View1, you might just want to be going back to the existing one. In that case, your code could just look like this:

struct Home: View {
    var body: some View {
        NavigationView {
            View1()
        }
    }
}

struct View1 : View {
    @State private var view2 = false
    
    var body: some View {
        VStack {
            Text("Home View!")
                .padding()
            
            NavigationLink(destination: View2(), isActive: $view2) { }
            
            Button {
                self.view2 = true
            } label: {
                Text("Go to next view")
            }
            
        }
        .navigationTitle("Home")
    }
}

struct View2: View {
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        VStack {
            Text("This is View 2")
                .padding()
            Button {
                presentationMode.wrappedValue.dismiss()
            } label: {
                Text("Go to Home view")
            }
            
        }
        .navigationTitle("View 2")
    }
}


  • Related