How to remove the default Navigation Bar space in SwiftUI NavigiationView

后端 未结 15 2637
我在风中等你
我在风中等你 2020-11-29 20:00

I am new to SwiftUI (like most people) and trying to figure out how to remove some whitespace above a List that I embedded in a NavigationView

In this image, you can

相关标签:
15条回答
  • 2020-11-29 20:09

    View Modifiers made it easy:

    //ViewModifiers.swift
    
    struct HiddenNavigationBar: ViewModifier {
        func body(content: Content) -> some View {
            content
            .navigationBarTitle("", displayMode: .inline)
            .navigationBarHidden(true)
        }
    }
    
    extension View {
        func hiddenNavigationBarStyle() -> some View {
            modifier( HiddenNavigationBar() )
        }
    }
    

    Example:

    import SwiftUI
    
    struct MyView: View {
        var body: some View {
            NavigationView {
                VStack {
                    Spacer()
                    HStack {  
                        Spacer()
                        Text("Hello World!")
                        Spacer()
                    }
                    Spacer()
                }
                .padding()
                .background(Color.green)
                //remove the default Navigation Bar space:
                .hiddenNavigationBarStyle()
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-29 20:11

    SwiftUI 2

    There is a dedicated modifier to make the navigation bar take less space:

    .navigationBarTitleDisplayMode(.inline)
    

    There's no longer need to hide the navigation bar or set its title.

    0 讨论(0)
  • 2020-11-29 20:13

    For me it was because I was pushing my NavigationView from an existing. In effect having one inside the other. If you are coming from a NavigationView you do not need to create one inside the next as you already inside a NavigatonView.

    0 讨论(0)
  • 2020-11-29 20:13

    My solution for this problem was the same as suggested by @Genki and @Frankenstein.

    I applied two modifiers to the inner list (NOT the NavigationView) to get rid of the spacing:

    .navigationBarTitle("", displayMode: .automatic)
    .navigationBarHidden(true) 
    

    On the outer NavigationView, then applied .navigationBarTitle("TITLE") to set the title.

    0 讨论(0)
  • 2020-11-29 20:14

    I also tried all the solutions mentioned on this page and only found @graycampbell solution the one to be working well, with well-working animations. So I tried to create a value I can just use throughout the app that I can access anywhere by the example of hackingwithswift.com

    I created an ObservableObject class

    class NavBarPreferences: ObservableObject {
        @Published var navBarIsHidden = true
    }
    

    And pass it on to the initial view in the SceneDelegate like so

    var navBarPreferences = NavBarPreferences()
    window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(navBarPreferences))
    

    Then in the ContentView we can keep track of this Observable object like so and create a link to SomeView:

    struct ContentView: View {
        //This variable listens to the ObservableObject class
        @EnvironmentObject var navBarPrefs: NavBarPreferences
    
        var body: some View {
            NavigationView {
                    NavigationLink (
                    destination: SomeView()) {
                        VStack{
                            Text("Hello first screen")
                                .multilineTextAlignment(.center)
                                .accentColor(.black)
                        }
                    }
                    .navigationBarTitle(Text(""),displayMode: .inline)
                    .navigationBarHidden(navBarPrefs.navBarIsHidden)
                    .onAppear{
                        self.navBarPrefs.navBarIsHidden = true
                }
            }
        }
    }
    

    And then when accessing the second view (SomeView), we hide it again like this:

    struct SomeView: View {
        @EnvironmentObject var navBarPrefs: NavBarPreferences
    
        var body: some View {
            Text("Hello second screen")
            .onAppear {
                self.navBarPrefs.navBarIsHidden = false
            }
        } 
    }
    

    To keep previews working add the NavBarPreferences to the preview like so:

    struct SomeView_Previews: PreviewProvider {
        static var previews: some View {
            SomeView().environmentObject(NavBarPreferences())
        }
    }
    
    0 讨论(0)
  • 2020-11-29 20:14

    Really loved the idea given by @Vatsal Manot To create a modifier for this.
    Removing isHidden property from his answer, as I don't find it useful as modifier name itself suggests that hide navigation bar.

    // Hide navigation bar.
    public struct NavigationBarHider: ViewModifier {
    
        public func body(content: Content) -> some View {
            content
                .navigationBarTitle("")
                .navigationBarHidden(true)
        }
    }
    
    extension View {
        public func hideNavigationBar() -> some View {
            modifier(NavigationBarHider())
        }
    }
    
    0 讨论(0)
提交回复
热议问题