Search code examples
swiftswiftui.searchable

Adding (vertical padding or padding top) space above .searchable() method


I want to add a space above the .searchable() method and have a gap of 20, that is padding(.top, 20). I don't want to use any customized search box. Can anyone please let me know if a gap can be provided above .searchable(). My text above the .searchable() overlaps with this input box.

else {
    NavigationView {
        mainContentView
            .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
            .onChange(of: searchText) { _, newValue in
                if !viewModel.isLoading {
                    viewModel.fetchOptions(for: newValue)
                }
            }
        
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Text("Home")
                        .font(.Title)
                        .bold()
                        .padding(.top, 180)
                        .padding(.bottom, 130)
                    
                }
                
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Edit") {
                    }
                    .padding(.top, 30)
                    .padding(.bottom, 30)
                }
            }
        
    }                    

I have added a picture for the reference. I want the search input box below the text Home, and there should be a little gap between Home and the input box. The placement of Edit and Home should be as it is.


Solution

  • In my tests, I found that the search bar is always shown in the same position, but you can move the items in the navigation bar up and down by a small amount by applying top or bottom padding.

    You are already applying a lot of padding and this is what is causing the title to move down over the search bar. Try less padding:

    mainContentView
        .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
        .onChange(of: searchText) { _, newValue in
            // ...
        }
        .toolbar {
            ToolbarItem(placement: .navigationBarLeading) {
                Text("Home")
                    .font(.Title)
                    .bold()
                    .padding(.bottom, 15)
            }
            ToolbarItem(placement: .navigationBarTrailing) {
                Button("Edit") {
                }
                .padding(.bottom, 15)
            }
        }
    

    Screenshot

    For more space above the title, you could also try setting the title as a .navigationTitle, instead of setting it as a ToolbarItem:

    mainContentView
        .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
        .onChange(of: searchText) { _, newValue in
            // ...
        }
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button("Edit") {
                }
            }
        }
        .navigationTitle("Home")
    

    Screenshot


    EDIT You asked in a comment whether it is possible to add spacing below the input search box. I don't quite understand why you said that top padding doesn't work, it works for me. If the gap should remain the same then you just need to keep the content pushed to the top. Two ways of doing this are:

    • apply .frame(maxHeight: .infinity, alignment: .top)
    • or, use a VStack with a Spacer() at the bottom.

    Here is an implementation of mainContentView to show it working using the .frame approach:

    private var mainContentView: some View {
        VStack {
            Text("mainContentView")
        }
        .frame(maxHeight: .infinity, alignment: .top)
        .padding(.top, 50)
    }
    

    Animation

    As you can see, the gap between the search input field and the top of the content remains constant. That's what you are wanting, right?